Qt 主GUI和其他线程 + 事件循环

9
我正在尝试理解Qt的整个内部流程以及在使用不同线程时如何工作。
据我所了解(通过谷歌搜索和探索Qt源代码),如下所示:
1. 每个线程都有一个本地的“待处理事件列表”和一个本地的事件循环(如果我调用`exec`),它与该列表进行交互。
2. `QCoreApplication::postEvent(obj, e)`将对`(obj, e)`对附加到`obj`线程的“待处理事件列表”上。
3. 每个线程都有一个本地的“事件分发器”(`QAbstractEventDispatcher`特化),其目的是读取系统事件。因此,存在适用于不同平台的`QEventDispatchWin`、`QEventDispatchUnix`、`QEventDispatchSymbian`等等。对于`gui`事件,Qt还具有`QEventDispatchX11`(从`QEventDispatchUnix`继承)、`S60`(来自`Symbian`)等等。
考虑到所有这些,`exec`调用的工作方式如下:
Thread's `exec`:
 ├ create a QEventLoop object.
 └ call QEventLoop.exec()
   └ call repeatedly eventDispatcher's processEvents with WaitForMoreEvents flag.
     ├ call to QCoreApplication::sendPostedEventswhile (!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).

如果调用了quitexit,它将结束当前processEvents调用,并使exec返回传递给exit的值。
需要考虑以下几点:
  1. 系统事件从系统生成并作为QEvent翻译时,永远不会被推送/发布:它们直接发送到目标对象。
  2. 目标对象成员函数(o.event())在与processEvent发生的同一线程中被调用。
现在,有一些疑问:
  1. postEvent是一个静态且线程安全的函数,那么QCoreApplication在这个事件处理系统中扮演什么角色?而QApplication呢?为什么必须尽快创建它们?
  2. 为什么需要QApplication/QCoreApplication来获取系统事件,如果每个线程都有自己的“事件分发器”?
欢迎对我的假设进行任何更正。
1个回答

3
作为对你的第二个问题的回应,“如果每个线程都有自己的“事件分发器”,为什么QApplication/QCoreApplication是获取系统事件的必需品?”
4.8文档说明如下:
“请注意,QCoreApplication::exec()必须始终从主线程(执行main()的线程)而不是从QThread中调用。在GUI应用程序中,主线程也称为GUI线程,因为它是唯一允许执行与GUI相关操作的线程。”
但是关于QThreads的一般情况 - 您会发现提供的链接将QThreads描述为包装线程的QObjects。因此,像任何其他QObjects一样,QThreads需要QCoreApplication进行交互,以协调通知/事件,例如当线程完成时。

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

在Maya的文章中,她提供了一个例子,其中任务被分配给QThread而不是在其中定义[即使用信号/槽并不要过载run()方法]。通过这种方式,您可以清楚地看到由QCoreApplication提供的主事件循环仍然发挥着关键作用。
正如您可能已经知道的那样,在这个网站上,围绕QThreads的话题已经有大量的讨论 - 并且Qt4有相当完整的文档......不能说Qt5也一样。=(

1
抱歉这么晚才将您的回复标记为答案,直到今天我才意识到。 - ABu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接