如何在Qt中将执行移动到另一个线程后侦听“已完成”指示

时间:2012-11-05 11:20:42

标签: qt qthread

我有一个非GUI操作,我打算在工作线程中执行。 经过一些谷歌搜索,我想出了一个简单的方法来实现这个here

特别是QMetaObject::invokeMethod()对我很好。我还注意不要对QThread进行子类化,而是继承QObject以创建我的worker对象,然后将该对象的线程关联性移动到新创建的线程。 (详细描述here

现在我的问题:

我将开始从我的主线程排队方法(我想这会发生在使用QEventLoop的引擎盖下,即使我没有设置一个,即使我没有重新实现QThread::run()或调用{{ 1}}) 我需要找出我的工人何时完成处理。换句话说,我需要知道QEventLoop何时为空。我以为我可以使用信号finished()。但它似乎不起作用。 有人可以说明如何找出工作线程何时完成执行? 如果您需要更多信息/代码,请告诉我。

Class Plugin是QObject的子类

QThread::exec()

...

Plugin::Plugin()
{
    m_workerThread = new QThread(this);
    m_workerThread->start(QThread::IdlePriority);
    m_worker = new DataWorker(this);
    connect(m_workerThread, SIGNAL(finished()), m_worker, SLOT(deleteLater()));    
    m_worker->moveToThread(m_workerThread);
}

在Dataworker类

Plugin::updateData()
{
....
if( true == QMetaObject::invokeMethod(m_worker, "RunFProcToGetData", Qt::QueuedConnection, Q_ARG(QString, foo)))
            {
                qDebug() << "successfully invoked RunFProcToGetData";
            }
            if( true == QMetaObject::invokeMethod(m_worker, "updateDataIntoDB", Qt::QueuedConnection, Q_ARG(QSqlDatabase, db),                                                Q_ARG(QString, foo)))
            {
                qDebug() << "successfully invoked updateDataIntoDB";
            }
....
}

所以当没有更多的updateDataIntoDB和RunFProcToGetData要处理时,我需要一个触发器

1 个答案:

答案 0 :(得分:0)

您不需要重新实现QThread :: run(),您的代码就可以了。默认run()将执行事件循环,并将执行排队的Dataworker插槽(Qt:QueuedConnection)。循环执行无限,直到您使用thread-&gt; quit()显式停止它。

我建议你把一些通知信号发送到你将从RunFProcToGetData(),updateDataIntoDB()发出的Dataworker类......这样你就可以将updateData()中最后一个被调用方法的通知信号连接到所需的插槽(可能在插件中)。该连接也将排队(如果对象在不同的​​线程中运行,Qt:QueuedConnection是默认的。)

这样,当updateData()中的所有排队方法完成执行时,您将收到通知。你可以多次调用updateData(); m_workerThread将运行排队的Dataworker插槽或空闲。记得停止线程并等待它在插件的析构函数中完成:

Plugin::~Plugin() {
    ...
    m_workerThread_->quit();
    m_workerThread_->wait();
    ...
}