I am trying to perform some work in a separate thread and stop that thread when the work is done.
I have set up a connection like this
thread.connect( workerClass, SIGNAL( finished() ), SLOT( quit() ) );
but the quit() slot is never called when I emit the finished() signal. The command line does not show any warnings related to failed connections.
I created a simple test project to narrow down the problem and I get the same behavior:
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();
};
and the 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;
}
So here is what I expected to happen:
- Once
testThread.start()
gets processed, the thread'srun()
function gets called, which internally callsexec()
and starts an event loop. Additionally it throws astarted()
signal. testClass
has itsdoWork()
slot called.- When
TestClass::doWork()
is done, it throws afinished()
signal. - The event loop of
testThread
receives the signal and forwards it to itsquit()
slot testThread.wait()
returns from waiting as the thread has ended.
Steps 1-3 work and I get the qDebug()
output.
The problem is at step 4: The signal is fired and forwarded to some event loop (I debugged it a bit, but couldn't figure out to which event loop it was fired) but the quit()
slot is never called.
What am I doing wrong?
P.S.: Please don't suggest subclassing QThread instead, the whole point of me trying this way out is because I want to avoid subclassing QThread.