Qt Call Slot Thread

Qt Call Slot Thread Average ratng: 5,0/5 9607 reviews

Last time I explained how plain C++ objects and their methods interact with threads. This time around, we will look at QObjects, and their “thread affinity”.

Now that we know object methods can be accessed by any thread at any time,we’ll consider the situation from the point of view of Qt.

When a Qt application starts, only one thread is running—the main thread. This is the only thread that is allowed to create the QApplication or QCoreApplication object and call exec on it. After the call to exec , this thread is either waiting for an event or processing an event. This is rather intuitive and easy to used. But when SLOTS and Qt event loop are used in the worker thread, some users do it wrong. Hughes, one of the Qt core developers, recommend that use worker objects by moving them to the thread using QObject::moveToThread. Unfortunately, some users went on a crusade against the former usage.

What are QObjects?

Slot

Qt is a great framework, and at its heart areQObjects.Through Qt’s moc compilerextra functionality is seemlessly added to C++ objects.The two most notable additions are signals and slots for inter-object communication, and events.These allow great flexibility and modularity, but how do they work in the context of threads?

For example, if an event or slot is triggered in a QObject (whichultimately triggers a function), which thread is calling that function? Theanswer lies in thread affinity. But let’s back up a bit.

Qt threads and Event loops

Having the ability to asynchronously trigger functions, and raise/handle eventsmeans that Qt must have some kind of an event loop. An event loop will continuallymonitor a queue of events to be handled, and dispatch them accordingly.Indeed, every QThread has a built-in event loop that can be entered.

One way to see this directly is by inheriting from QThread:

Slot

The above is a good example for demonstration, but is rarely done in production. We will see a better way to run custom code on QThreads in the next section.

In particular the GUI thread (the main thread), also has an event loop which islaunched by calling QApplication::exec(), which only returns after the user has quit the program.

So far the most important thing to remember is:

Threads in Qt handle asynchronous events, and thus all have an event-loop.

QObjects and QThreads

Now we come to the meat of this post- if C++ objects can be accessed by anythread, then what thread is handling the events of a particular QObject?The answer is that whenever a QObject is created, it is assigned a parent threadwhich handles all of it’s events and slot invocations- it has a threadaffinity. Whichever thread it was created in, becomes it’s parent thread!

This is where the confusion came about for me. On the one hand C++ objectmethods can be called from any thread at any time, while QObjects (themselvesC++ objects) have a parent thread which handles its events. As you can hopefullysee, there is no conflict:

Qt call slot thread tool

QObject methods can be called from any thread at any time, just like a C++object. In addition, a parent thread is assigned to handle anyasynchronous events and slot invocations.

So there are two ways for a function to be called on a QObject:

  • Directly from any thread
  • Indirectly by invoking a connected slot or raising an event. This posts an event onto the parent thread’s event loop, which eventually calls the function in question.

To complete this article, let’s look at running our code on other threads.As promised before we will not inherit from QThread for the job.If we can’t customize a thread, and QObjects are bound to the thread that created them, how can we achieve this? Qt allows users to moveQObjects to other threads, thereby changing the thread affinity to the new thread:

This is much simpler and easier to follow than subclassing a QThread each time you want to create a worker thread.Thanks to Jurily for suggesting this in a reddit comment.

Qt Call Slot From Another Thread

I hope you enjoyed this simplified rundown of QObjects and threads! More in-depth documentation can be found on the Qt-project website.