QThread
is a handle to a platform thread. It lets you manage the thread by monitoring its lifetime, and requesting that it finishes its work.
In most cases inhering from the class is not recommended. The default run
method starts an event loop that can dispatch events to objects living in the class. Cross-thread signal-slot connections are implemented by dispatching a QMetaCallEvent
to the target object.
A QObject
instance can be moved to a thread, where it will process its events, such as timer events or slot/method calls.
To do work on a thread, first create your own worker class that derives from QObject
. Then move it to the thread. The object can run its own code automatically e.g. by using QMetaObject::invokeMethod()
.
#include <QObject>
class MyWorker : public QObject
{
Q_OBJECT
public:
Q_SLOT void doWork() {
qDebug() << "doWork()" << QThread::currentThread();
// and do some long operation here
}
MyWorker(QObject * parent = nullptr) : QObject{parent} {}
};
class MyController : public QObject
{
Q_OBJECT
Worker worker;
QThread workerThread;
public:
MyController() {
worker.moveToThread(&workerThread);
// provide meaningful debug output
workerThread.setObjectName("workerThread");
workerThread.start();
// the thread starts the event loop and blocks waiting for events
}
~MyController() {
workerThread.quit();
workerThread.wait();
}
void operate() {
// Qt::QueuedConnection ensures that the slot is invoked in its own thread
QMetaObject::invokeMethod(&worker, "doWork", Qt::QueuedConnection);
}
};
If your worker should be ephemeral and only exist while its work is being done, it's best to submit a functor or a thread-safe method for execution in the thread pool via QtConcurrent::run
.