Nyaruko
Nyaruko

Reputation: 4479

Qt: How to clean up a QThread when you do not subclass it?

If I have the most standard code of using a QThread like this:

myClass* object = new myClass();
QThread* worker = new QThread();
object->moveToThread(worker);
worker->start();

Then what is the proper way to delete object and the proper way to quit the worker thread?

If I don't delete object there will be memory leakage.

If I don't quit worker, when I close the application, there will be warning said that QThread is destroyed while it is still running.

Upvotes: 2

Views: 4149

Answers (3)

thuga
thuga

Reputation: 12931

To delete your object object, you can connect the QThread::finished signal of your worker object to the QObject::deleteLater slot of your object object.

And to quit your thread, you can call QThread::quit and QThread::wait in the destructor of your class (or whenever you need to stop your thread).

MyClass::~MyClass()
{
    thread->quit();
    thread->wait();
    ...
}

To delete your worker object, you can just set a parent to it, or make it an automatic member variable. You can also use a smart pointer for it.

By the way, your naming convention is a bit odd. The QThread object in your case is not a worker, it just manages the thread. The myClass object would be the worker in your case.

Upvotes: 3

Marek R
Marek R

Reputation: 37697

Connecting QThread::finished and QObject::deleteLater is wrong. If signal QThread::finished is emitted this means that thread event loop will not run again so slot QObject::deleteLater will not be called. So accepted answer is wrong.

It is better to do it like that:

myClass* object = new myClass();
QThread* worker = new QThread(parent);
object->moveToThread(worker);

connect(object, &QObject::destroyed, worker, &QThread::quit, Qt::DirectConnection);
connect(someObject, SIGNAL(stoItSignal()), object, &QObject::deleteLater);
worker->start();

At some point it might be needed to wait for tread, (for example when main window is destroyed) to clean up things, so this statement could be useful (in this case Qt::DirectConnection in code above is obligatory):

object->deleteLater();
worker->wait(3000);

Upvotes: 0

Marian Munteanu
Marian Munteanu

Reputation: 359

Here's a basic usage:

Define a worker class:

class MyWorkerClass {
    signals:
    void Finished();

    public slots:
    void RunCode(){
        //...
        // add your code here
        //...
        emit Finished();
    }
}

How to use your worker class:

MyWorkerClass * workerObject = new MyWorkerClass();
QThread * workerThread = new QThread();

workerObject->moveToThread(workerThread);

connect(workerThread, &QThread::started, workerObject, &MyWorkerClass::RunCode);
connect(workerObject, &MyWorkerClass::Finished, workerThread, &QThread::quit);

workerThread->start();
workerObject->deleteLater();

Upvotes: 0

Related Questions