The Recommended Way to Use QThread

by BlackBerry Development Advisor on ‎08-02-2012 05:19 PM (12,947 Views)

QT provides QThread for threaded applications. Unfortunately, there is some confusion around how to use QThreads. This article provides some background and explains how you should use QThreads in your applications.

Do not subclass QThread!
Much of the QThread confusion stems from the fact that QThread used to be an abstract class. Thus, the only way to use QThread was to subclass it and provide an implementation of the run() method. Since version 4.4 QThread::run() has gained a default implementation hence the subclassing approach should no longer be used.  A key reason for this is because subclassing QThread can prevent it from uisng slots.

 

The main remaining use case for subclassing QThread is when you wish to create your own application run-loop.

 

Use moveToThread() and a worker QObject.
This is how you should implement a threaded operation using QThread. First start by creating a worker class that inherits QObject. This class should define:

 

  • A slot where all the work is done.
  • A signal for signaling when the work is finished.
  • ( Optionally a signal for notifying if something fails. )

 

class Worker : public QObject{
  Q_OBJECT
public:
  Worker();
  virtual ~Worker();
public slots:
  void process();

signals:
  void finished();
  void error(QString err);
};

 

 

Now it’s time to use a QThread with your worker class to actually do the threaded processing.

 

// Create a thread
QThread* thread = new QThread;
Worker* worker = new Worker();

// Give QThread ownership of Worker Object
worker->moveToThread(thread);

// Connect worker error signal to this errorHandler SLOT.
connect(worker, SIGNAL(error(QString)), this, SLOT(errorHandler(QString)));

// Connects the thread’s started() signal to the process() slot in the worker, causing it to start.
connect(thread, SIGNAL(started()), worker, SLOT(process()));

// Connect worker finished signal to trigger thread quit, then delete.
connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));

// Make sure the thread object is deleted after execution has finished.
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));

thread->start();

 

 

Additional Resources

Qt Labs Developer Blogs - You’re doing it wrong…