QtQuick动画冻结列表和打开串行端口 [英] QtQuick animation freezing on list and open serial ports
问题描述
我写了一个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屋!