別のスレッドでいくつかの作業を実行し、作業が完了したらそのスレッドを停止しようとしています。
このような接続を設定しました
thread.connect( workerClass, SIGNAL( finished() ), SLOT( quit() ) );
しかし、終了した()シグナルを発したときに、quit()スロットが呼び出されることはありません。コマンド ラインには、失敗した接続に関連する警告は表示されません。
問題を絞り込むために簡単なテスト プロジェクトを作成しましたが、同じ動作が得られます。
TestClass.h:
#ifndef TESTCLASS_H
#define TESTCLASS_H
class TestClass : public QObject
{
Q_OBJECT
public:
TestClass() { }
signals:
void finished();
public slots:
void doWork();
}
#endif // TESTCLASS_H
TestClass.cpp:
#include "TestClass.h"
#include <QtCore/QDebug>
void TestClass::doWork()
{
qDebug() << "Starting";
for( long i = 0; i < 1000000000; i++ );
qDebug() << "Done";
emit finished();
};
そしてmain.cpp:
#include <QtCore/QCoreApplication>
#include <QtCore/QThread>
#include "TestClass.h"
int main( int argc, char* argv[] )
{
QCoreApplication a( argc, argv );
TestClass testClass;
QThread testThread;
testClass.moveToThread( &testThread );
testThread.connect( &testClass, SIGNAL( finished() ), SLOT( quit() ) );
testClass.connect( &testThread, SIGNAL( started() ), SLOT( doWork() ) );
testThread.start();
testThread.wait();
return 0;
}
だからここに私が起こると予想したものがあります:
- 処理が完了
testThread.start()
すると、スレッドのrun()
関数が呼び出され、内部的exec()
にイベント ループが呼び出されて開始されます。さらに、シグナルをスローしstarted()
ます。 testClass
doWork()
と呼ばれるスロットを持っています。- 完了すると、シグナル
TestClass::doWork()
がスローされます。finished()
- のイベントループは
testThread
シグナルを受信し、それをそのquit()
スロットに転送します testThread.wait()
スレッドが終了したため、待機から戻ります。
ステップ 1 ~ 3 が機能し、qDebug()
出力が得られます。問題はステップ 4 にあります: シグナルが発生し、いくつかのイベント ループに転送されます (少しデバッグしましたが、どのイベント ループに発生したのかわかりませんでした) が、quit()
スロットは呼び出されません。
私は何を間違っていますか?
PS: 代わりに QThread をサブクラス化することを提案しないでください。私がこの方法を試しているのは、QThread のサブクラス化を避けたいからです。