2

我有一个QString导出到 qml 的对象。在C++代码中更新值并为属性发出更改的信号时,它不会更新它,因为线程很忙:那时我在 for 循环中使用了成本操作。为此,我曾经QCoreApplication::processEvents()能够在循环的每次迭代中发出延迟信号,例如:

foreach(const QVariant& item, _manifestFile) {
    setStatusString(QString("Checking file %1 of %2...").arg(currentProcessingFile++).arg(totalFilesCount));
    QCoreApplication::processEvents();  // TODO remove
    //...
}

我上面描述的我的变量setStatusString的设置器在哪里:QString

void Updater::setStatusString(const QString &statusString) {
    _statusString = statusString;

    emit statusStringChanged();
}

我怎样才能删除它processEvents()并能够发出信号?任何解决方案都值得赞赏:线程、Qt-meta 对象等。

4

1 回答 1

0

您应该Updater在堆上创建类的对象并将其移动到新线程,以防止 for 循环阻塞主线程和 UI。这可以像这样完成:

updater = new Updater();
QThread * th = new QThread();
updater->moveToThread(th);

QObject::connect(th,SIGNAL(started()),updater,SLOT(OnStarted()));
QObject::connect(th,SIGNAL(finished()),updater,SLOT(OnFinished()));

QObject::connect(updater,SIGNAL(statusStringChanged(QString)),this,SLOT(updateString(QString)));

th->start();

您在类中的初始化和终止任务Updater应该分别在OnStarted()OnFinished()插槽中完成。

现在您可以发出具有适当值的信号,该信号将在适当的时间排队和处理。您可以在某个时间间隔内定期在计时器中发出信号,以防止发出过于频繁。

最后一点是,Updater当函数在另一个线程中时,你不应该直接调用它。正确的方法是将函数定义为插槽并将信号连接到该插槽并在您想要调用特定函数时发出信号。

于 2015-01-09T08:41:01.693 回答