Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qt Main-Gui and other thread + events loops

I'm trying to understand the whole internal process of Qt and how it works when I'm working with different threads.

As I've understood (googling and exploring the Qt source code), is as following:

  • Each thread has a local "pending event list" and a local event loop (if I call to exec) that interacts with that list.
  • QCoreApplication::postEvent(obj, e) appends the pair (obj, e) on the "pending event list" of the obj's thread.
  • Each thread has a local "event dispatcher" (QAbstractEventDispatcher specializations), which purpose is reading system events. So, it exists a QEventDispatchWin, a QEventDispatchUnix, a QEventDispatchSymbian and so on, for different platforms. For gui events, Qt has also QEventDispatchX11 (inherits from QEventDispatchUnix), S60 (from Symbian), etc.

With of all this in mind, a exec call works as following:

Thread's `exec`:
 ├ create a QEventLoop object.
 └ call QEventLoop.exec()
   └ call repeatedly eventDispatcher's processEvents with WaitForMoreEvents flag.
     ├ call to QCoreApplication::sendPostedEvents
     ├ while (!pending system events)
     │  ├ read system event
     │  ├ create an appropiate QEvent e and detect its target QObject o.
     │  └ call to QCoreApplication::sendSpontaneousEvent(o, e)
     └ call to QCoreApplication::sendPostedEvents
       (for new generated user events in the previous step).

If quit or exit is called, it finalices the current processEvents call and exec returns with the value passed to exit.

Some points to take in consideration:

  1. System events are never pushed/posted: when they are generated from the system and translated as QEvents, they are directly sended to its target object.
  2. Target object member functions (o.event()) are called in the same thread where processEvent takes place.

And now, doubts:

  1. Since postEvent is a static and thread-safe function, what role does QCoreApplication play in this event processing system? And QApplication? Why are they mandatory to being created as soon as possible?
  2. Why QApplication/QCoreApplication are mandatory to get system events, if each Thread has its own "event dispatcher"?

Any correction about my supositions are welcome.

like image 801
Peregring-lk Avatar asked May 29 '13 11:05

Peregring-lk


People also ask

What is Qt event loop?

An event loop in a thread makes it possible for the thread to use certain non-GUI Qt classes that require the presence of an event loop (such as QTimer, QTcpSocket, and QProcess). It also makes it possible to connect signals from any threads to slots of a specific thread.

Is QT multithreaded?

Qt offers many classes and functions for working with threads. Below are four different approaches that Qt programmers can use to implement multithreaded applications.

How do you use QThread?

To use it, prepare a QObject subclass with all your desired functionality in it. Then create a new QThread instance, push the QObject onto it using moveToThread(QThread*) of the QObject instance and call start() on the QThread instance. That's all.

How do you create a thread in Qt?

We make the MyThread class get inherited from QThread. In the code, we creates three instances of MyThread class with QString names ("A", "B", and "C"). The void QThread::start(Priority priority = InheritPriority) slot begins execution of the thread by calling run() which we overrides in MyThread class.


1 Answers

In response to your second question, "Why QApplication/QCoreApplication are mandatory to get system events, if each Thread has its own "event dispatcher"?"

The 4.8 documenation states:

"Note that QCoreApplication::exec() must always be called from the main thread (the thread that executes main()), not from a QThread. In GUI applications, the main thread is also called the GUI thread because it's the only thread that is allowed to perform GUI-related operations."

But regarding QThreads in general - you'll find the the link provided describes QThreads as QObjects that is a wrapper around threads. So QThreads, like any other QObjects, require the QCoreApplication to interact with in order to coordinate notifications/events, e.g. when the thread finishes.

http://qt-project.org/forums/viewthread/14806

In Maya's article, she provides an example where tasks are ASSIGNED to a QThread instead of being defined within [i.e. use signals/slots and don't overload the run() method]. In this way, you clearly see that the main event loop provided by QCoreApplication still plays a crucial role.

As you probably already know, there has already been an abundant amount of discussion revolving around the topic of QThreads on this site - and Qt4 is pretty well-documented... can't say the same for Qt5 =(

like image 98
Huy Avatar answered Sep 23 '22 09:09

Huy