2

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

特别QMetaObject::invokeMethod()适合我。我还注意不要对 QThread 进行子类化,而是对 QObject 进行子类化以创建我的工作对象,然后将该对象的线程亲和性移动到新创建的线程。(这里有详细描述

现在我的问题:

我将从我的主线程开始对方法进行排队(我想这发生在使用 QEventLoop 的幕后,即使我没有设置一个,即使我没有重新实现QThread::run()或调用QThread::exec())我需要找出我的工人什么时候有加工完毕。换句话说,我需要知道 QEventLoop 何时为空。我想我可以为此使用信号finished()。但它似乎不起作用。有人可以阐明如何找出工作线程何时完成执行吗?如果您需要更多信息/代码,请告诉我。

类插件是 QObject 的子类

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);
}

...

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";
            }
....
}

在数据工作者类中

Dataworker::RunProcToGetData(const QString &foo)
{
// invoke a program to get the Data
}


Dataworker::updateDataIntoDB(const QSqlDatabase& db, const QString &foo)
{
// Update database 
}

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

4

1 回答 1

0

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

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

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

Plugin::~Plugin() {
    ...
    m_workerThread_->quit();
    m_workerThread_->wait();
    ...
}
于 2013-08-28T14:57:43.790 回答