Search code examples
c++multithreadingqt

How to setup signal/slot connection between thread and child thread?


I have a class ParentThread deriving from QThread with the following run() method that roughly looks as follows:

void ParentThread::run()
{
  QThread *childThread = new QThread;
  QObject::connect(childThread, SIGNAL(finished()), this, SLOT(onChildThreadFinished());
  QObject::connect(childThread, SIGNAL(finished()), childThread, SLOT(deleteLater());
  childThread->start();

  exec();
}

The slot onChildThreadFinished() is defined on ParentThread, and should run in the context of ParentThread. However, using the code above, onChildThreadFinished only gets called in case the signal/slot connection is a Qt::DirectConnection, but then runs in the context of the child thread. In case the signal/slot connection is defined as a Qt::QueuedConnection, the slot never gets called. I am using Qt 4.8.5. Any idea what the issue is here?


Solution

  • You state that The slot onChildThreadFinished() is defined on ParentThread, and should run in the context of ParentThread. This assumption is wrong. This is one of the reasons why subclassing QThread is discouraged.

    If you want to use slots in your threads, subclassing QThread is not what you want to do. Use worker-object method instead. Subclass QObject and call QObject::moveToThread to move your object to a new thread.

    Here is what Qt docs say about this:

    It is important to remember that a QThread instance lives in the old thread that instantiated it, not in the new thread that calls run(). This means that all of QThread's queued slots will execute in the old thread. Thus, a developer who wishes to invoke slots in the new thread must use the worker-object approach; new slots should not be implemented directly into a subclassed QThread.