Qt Main-Gui和其他线程+事件循环

时间:2013-05-29 11:24:28

标签: qt event-handling qt4 qthread

我正在尝试理解Qt的整个内部过程以及当我使用不同的线程时它是如何工作的。

正如我所理解的(谷歌搜索和探索Qt源代码),如下:

  • 每个线程都有一个本地“待处理事件列表”和一个与该列表交互的本地事件循环(如果我调用exec)。
  • QCoreApplication::postEvent(obj, e)(obj, e)对添加到obj主题的“待处理事件列表”中。
  • 每个线程都有一个本地“事件调度程序”(QAbstractEventDispatcher特化),其目的是读取系统事件。因此,对于不同的平台,它存在QEventDispatchWinQEventDispatchUnixQEventDispatchSymbian等等。对于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::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).

如果调用quitexit,则会终止当前processEvents来电和exec返回,并将值传递给exit

需要考虑的一些要点:

  1. 永远不会推送/发布系统事件:当它们从系统生成并翻译为QEvents时,它们会直接发送到目标对象。
  2. 目标对象成员函数(o.event())在发生processEvent的同一线程中调用。
  3. 现在,怀疑:

    1. 由于postEvent是一个静态且线程安全的函数,QCoreApplication在此事件处理系统中扮演什么角色?和QApplication?为什么要尽快创建它们?
    2. 如果每个线程都有自己的“事件调度程序”,为什么QApplication / QCoreApplication必须获取系统事件?
    3. 欢迎任何关于我的沉淀的纠正。

1 个答案:

答案 0 :(得分:2)

回答您的第二个问题,“如果每个线程都有自己的”事件调度程序“,为什么QApplication / QCoreApplication必须获取系统事件?”

4.8文件说明:

  

“请注意,QCoreApplication :: exec()必须始终从主线程(执行main()的线程)调用,而不是从QThread调用。在GUI应用程序中,主线程也称为GUI线程,因为它是唯一允许执行GUI相关操作的线程。“

但是对于一般的QThreads - 你会发现提供的链接将QThreads描述为QObjects,它是线程的包装器。因此,QThreads与任何其他QObject一样,需要QCoreApplication进行交互以协调通知/事件,例如,当线程完成时。

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

在Maya的文章中,她提供了一个示例,其中任务被分配给QThread而不是在[...]中定义使用信号/插槽,不要重载run()方法]。通过这种方式,您可以清楚地看到QCoreApplication提供的主要事件循环仍然起着至关重要的作用。

正如您可能已经知道的那样,围绕QThreads这个主题的讨论已经有很多 - 而且Qt4已经很好地记录了......对于Qt5来说不能说相同=(