QtQuick动画冻结列表和打开串行端口 [英] QtQuick animation freezing on list and open serial ports

查看:226
本文介绍了QtQuick动画冻结列表和打开串行端口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个C ++方法来找到所有串口,打开,写和关闭,并使用Q_INVOKABLE从一个QML调用这个方法。在QML,首先我推一个LoadingPage.qml到StackView,然后我调用find()串行端口,在onClicked:按钮插槽。

I wrote a C++ method to find all serial ports, open, write and close and use to Q_INVOKABLE to call this method from a QML. At QML, first I push a LoadingPage.qml to StackView and then I call the find() Serial Ports, inside the onClicked: Button slot.

问题:一个冻结推送一个LoadingPage.qml到StackView如果有很多串口连接,动画开始然后立即冻结,当功能找到完成动画再次开始。 [SerialPort.qml]
如何更好地解决这个问题?

The problem: It is a freezing on push a LoadingPage.qml to StackView if there are many serial ports connected, the animation start and then immediately freezes, when the function find finish the animation start again. [SerialPort.qml] How is it the better way to solve that?

//SerialPort.qml
Button {
    text: qsTr("start")
    onClicked: {
        stackView.push(Qt.resolvedUrl("LoadingPage.qml"))
        module.find()
    }
}


QVector<QString> Physical::find()
{
    m_ports.clear();

    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
        bool hasError = false;

        QSerialPort port;
        port.setPort(info);

        if (port.open(QIODevice::ReadWrite)) {
            if (!hasError && !port.setBaudRate(serial::baudRate)) {
                emit error(tr("Can't set baud to %1, error %2")
                           .arg(port.portName())
                           .arg(port.error()));
                hasError |= true;
            }
            if (!hasError && !port.setDataBits(serial::dataBits)) {
                emit error(tr("Can't set data bits to %1, error %2")
                           .arg(port.portName())
                           .arg(port.error()));
                hasError |= true;
            }

            if (!hasError && !port.setParity(serial::parity)) {
                emit error(tr("Can't set parity to %1, error %2")
                           .arg(port.portName())
                           .arg(port.error()));
                hasError |= true;
            }
            if (!hasError && !port.setStopBits(serial::stopBits)) {
                emit error(tr("Can't set stop bits to %1, error %2")
                           .arg(port.portName())
                           .arg(port.error()));
                hasError |= true;
            }
            if (!hasError && !port.setFlowControl(serial::flowCtrl)) {
                emit error(tr("Can't set flow control to %1, error %2")
                           .arg(port.portName())
                           .arg(port.error()));
                hasError |= true;
            }
            if (!hasError) {
                m_ports.append(port.portName());
            }

            QByteArray data;
            data.resize(1);
            data[0] = ID_READ;

            port.write(data);
            port.close();
        }
    }

    return m_ports;
}


推荐答案

线程,因为它阻止GUI线程,用户交互也会停止。

Your code runs in the GUI thread, and since it blocks the GUI thread, the user interaction is stopped as well.

您需要在单独的线程中执行扫描。 Qt并发框架是完美的,因为你正在执行一个自包含的操作,可以在任何线程中完成。您的 find()方法可以转换为独立函数或静态方法(因为这是真正的)。您还可以在lambda中捕获 this

You need to perform the scan in a separate thread. The Qt Concurrent framework is perfect for this, since you're performing a self-contained action that can be done in any thread. Your find() method can be turned into a stand-alone function or a static method (since that's what it really is). You could also capture this in a lambda.

然后运行它如下:

class Physical {
  QFuture<QStringList> m_future;
  QFutureWatcher<QStringList> m_futureWatcher;
  // A string list is a simpler type to type :)
  static QStringList doFindPorts() {
    ...
  }
  Q_SLOT void findPortsFinished() {
    QStringList ports(m_future);
    // use the list of ports
  }

public:
  Physical() {
    connect(&m_futureWatcher, SIGNAL(finished()), SLOT(findPortsFinished()));
    m_futureWatcher.set(m_future);
    ...
  }
  Q_SLOT void findPorts() {
    if (m_future.isRunning()) return;
    m_future = QtConcurrent::run(doFindPorts);
  }
};

这篇关于QtQuick动画冻结列表和打开串行端口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆