Confusion regarding QThread, QObject, Thread Affinity and Event Loop

c++, qeventloop, qobject, qt, qthread

Solution

"which is contradictory with the aforementioned intended use. Am I missing something?"

Yes, I think you're misunderstanding the concept of thread affinity (the thread on which an object is running).

Let's take an example with minimal code: -

QThread* pThread = new QThread; // QThread on the main thread
MyObject* myObj = new MyObject; // MyObject on the main thread
myObj->moveToThread(pThread);   // MyObject on the new thread, controlled by pThread
pThread->start();               // pThread instance is still on the main thread

Assuming this code has been created from an object whose thread affinity is the main thread, such as `QMainWindow`, the thread object `pThread` is running on the main thread; it's thread affinity is the main thread.

In contrast, the `QObject` derived `MyObject` instance, `myObj`, has been moved to the new thread `pThread`. So, the thread affinity of `myObj` is now the new thread.

The "functions written for `QThread`" are still called directly from the main thread, as that's where it's running.

Think of `QThread` as a thread controller object, rather than the thread itself. This is one of the reasons why it is often discouraged to inherit from `QThread`, unless you want to change how `QThread` manages the underlying thread.

how there can be more than one event loop in a single thread ?...

I've not used this directly myself, but I'll try to explain this as I understand it. Perhaps someone else will be able to correct or confirm this. From the Qt Documentation for QEventLoop, it states: -

At any time, you can create a `QEventLoop` object and call `exec()` on it to start a local event loop.

The signature from QEventLoop exec is: -

int QEventLoop::exec ( ProcessEventsFlags flags = AllEvents )

So if you pass in a set of flags, only these events would be handled. Now, as calling `exec()` starts the processing of events until `exit()` is called, you can create a local event loop that lets your program wait until one or more specific events occur.

A second event loop is a local event loop within the main event loop, but as each event loop can process the whole event queue, which is shared by all event loops in a thread, it can be used to override event handling from the main event loop.

If you conceptualise an event loop as doing something like this (pseudo code): -

QList<QEvent*> eventList;
while(!stop)
{
    // handle events in eventList
}

A 2nd event loop would then do this: -

bool bStop = false;
QList<QEvent*> eventList;
while(!bStop)
{
    // handle events in eventList
    ...
    ...
    // Inner event loop
    bool bStop = false;
    while(!bStop)
    {
        // handle events in eventList
    }
}

Problem

I was going through the links - You are doing it wrong - Using QThread in right way Part1 - Using QThread in right way Part2 I got confused by some statements. In the first link, it says that all of the functions in QThread were written and intended to be called from the creating thread, not the thread that QThread starts. while it suggests to use `moveToThread` to move an object to new thread, instead of subclassing `QThread`. My question is: The default implementation of `run` method calls `exec`, which creates an event loop, and when an object's thread affinity is changed using `moveToThread`, all the `slots` will be executed in the new thread, not on the creating thread, which is contradictory with the aforementioned intended use. Am I missing something? Second question: In the third link it is said event queue is belong to thread instead of event loop, and it’s shared by all the event loops running in this thread. My question is how there can be more than one event loop in a single thread ? What I understand is, event-loop loop through the event-queue, until `exit`/`terminate` is called, and processes each `event` arrives on that queue. If this is true, one loop will never end (unless `exit`/`terminate` is called), how another can begin? Any sample code demonstrating it will be highly appreciated.

Original source