2

ワーカー スレッドで実行する予定の非 GUI 操作があります。グーグルで調べた後、ここでこれを達成する簡単な方法を見つけました

特に がQMetaObject::invokeMethod()よく似合います。また、QThread をサブクラス化せず、代わりに QObject をサブクラス化してワーカー オブジェクトを作成し、このオブジェクトのスレッド アフィニティを新しく作成されたスレッドに移動するように注意しました。(ここに少し詳しく書かれています

今私の質問:

メインスレッドからメソッドのキューイングを開始します (これは、QEventLoop を設定していなくても、再実装QThread::run()も呼び出しもしていなくても、内部で QEventLoop を使用して発生しているとQThread::exec()思います)処理を終了しました。つまり、QEventLoop がいつ空になるかを知る必要があります。これにはシグナル finished() を使用できると思いました。しかし、うまくいかないようです。ワーカースレッドの実行がいつ終了したかを知る方法について、誰かが光を当てることができますか? さらに情報/コードが必要な場合は、お知らせください。

Class Plugin は 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 クラスで

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() で明示的に停止するまで無限に実行されます。

RunFProcToGetData()、updateDataIntoDB()、...から発行する Dataworker クラスにいくつかの通知シグナルを配置することをお勧めします。これにより、updateData() で最後に呼び出されたメソッドからの通知シグナルを目的のスロットに接続できます。 (おそらくプラグイン内)。その接続もキューに入れられます (オブジェクトが異なるスレッドで実行される場合、Qt:QueuedConnection がデフォルトです)。

そうすれば、 updateData() からキューに入れられたすべてのメソッドの実行が終了したときに通知されます。updateData() を複数回呼び出すことができます。m_workerThread は、キューに入れられた Dataworker スロットを実行するか、アイドル状態になります。スレッドを停止し、プラグインのデストラクタでスレッドが完了するまで待機することを忘れないでください。

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