How to properly delete and terminate QThread

12,762

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.

Share:
12,762
Niklas
Author by

Niklas

Updated on July 14, 2022

Comments

  • Niklas
    Niklas almost 2 years

    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();
    }
    
  • Mitch
    Mitch over 4 years
    doc.qt.io/qt-5/qthread.html#requestInterruption says: "This function does not stop any event loop running on the thread and does not terminate it in any way." This matches what I see if I use the code above: without calling quit() after requestInterruption(), the thread (i.e. the wait() call) never finishes.