Niklas Niklas - 21 days ago 6
C++ Question

How to properly delete and terminate QThread

I have got a subclass

MyClass
which inherits from
QThread
.

I create it like this with a parent to the
MainWindow
instance (this):

mMyClass = new MyClass("some_value", 1, 5L, this);


My understanding of how Qt deals with object deletion is that every
QObject
, which has a parent gets deleted when the parent gets deleted.

If my program does finish I get a warning
QThread: Destroyed while thread is still running


How can I fix this one up? I tried it with the following code in the deconstructor of
MainWindow
. Unfortunately it does not work properly:

if (mMyClass != 0 && mMyClass->isRunning()) {
mMyClass->deleteLater();
mMyClass->quit();
mMyClass->wait();
}

Answer

You have not specified what version of Qt you use, so I'm supposing 5.3.

Also, I believe in your thread code you have some form of infinite loop like the following:

while (1) {
    // do something here.
}

First of all, the best is to connect the thread deleteLater() slot to the finished() signal after the creation of the thread:

mMyClass = new MyClass("some_value", 1, 5L, this);
connect(mMyClass, SIGNAL(finished()), mMyClass, SLOT(deleteLater()));

This will cause the thread to be deleted by its parent as soon as possible after the thread finishes its job.

Now, to finish the job, Qt 5.2 introduced the methods QThread::requestInterruption() and QThread::isInterruptionRequested(). You can use these methods to tell your thread to finish with a code like this:

In your main class exit code:

if (mMyClass != 0 && mMyClass->isRunning() ) {
    mMyClass->requestInterruption();
    mMyClass->wait();
}

In your thread code:

while ( !this->isInterruptionRequested() ) {
    // do your job here!
}

What will happen is that when the code that closes your main window is called, it will "interrupt" the thread (if it is valid and running). The thread will check if it has been interrupted and will exit, triggering the finished() signal, which will trigger the deleteLater() slot and finally your main window will delete the class either at the event loop or at the class clean up.

Check the Qt 5.3 docs for more details.

Comments