Qt:将事件发布到 QThread 的正确方法?

Posted

技术标签:

【中文标题】Qt:将事件发布到 QThread 的正确方法?【英文标题】:Qt: Correct way to post events to a QThread? 【发布时间】:2011-09-06 16:35:37 【问题描述】:

在我的 Qt 应用程序中,我有一个主线程和一个工作线程。工作线程子类QThread 并通过customEvent 处理事件。这是主线程发送事件由工作线程处理的正确方式吗?

QThread* myWorkerThread = // ...

QApplication::instance()->postEvent (myWorkerThread, new MyWorkRequestEvent(/* ... */);

如果我正确阅读了文档,它表明事件是在拥有事件接收者的对象的线程上处理的。由于QThread 是由主线程创建的,所以它归主线程所有——那么这个事件是否会由主线程处理(这会违反直觉,在我的情况下是错误的)?

【问题讨论】:

【参考方案1】:

你的理解是正确的,确实很不直观:)

很多问题都来自于 QThread 的文档,该文档建议子类化 QThread。虽然 Qthread 有自己的事件循环,但只有在 run() 方法中创建(在该线程中创建)的 QObjects 的事件和信号才会在 QThread 事件循环中处理。

最好将线程逻辑封装在 QObject 子类中,然后将该对象移动到普通 QThread 的实例中。然后,您可以使用信号(将跨线程边界正确排队)或自定义事件与该 QObject 进行通信。

similar question 中有一些链接应该会有所帮助。

【讨论】:

第三段+1:让我们传播正确的穿线方式【参考方案2】:

事件由位于QApplicationQCoreApplication 中的主事件循环处理。因此,在其他线程中将事件发送到 QObjects 是没有意义的(除非您在那里创建另一个事件循环,我不确定这是否可行)。

不过,您可以将来自其他线程的事件发送到您的主线程。您示例中的 myWorkerThread 归主线程所有,因为它是在那里创建的。您的工作线程在run() 及以下创建的对象归该线程所有。

您还可以向其他线程中的插槽发送信号,例如,如果您想从您的工作线程或类似线程中绘制一个小部件(必须在主线程中完成)。

【讨论】:

QThread 有自己的事件循环,但发布到 QThread 本身的事件不会在该循环中处理。 我刚查了文档,我不知道QThread有自己的事件循环^^但是它需要明确地以exec()开头,这在工作线程中没有意义,因为在调用quit() 之前它不会返回。

以上是关于Qt:将事件发布到 QThread 的正确方法?的主要内容,如果未能解决你的问题,请参考以下文章

Qt - QThread(翻译帮助文档)

如何在 Qt 中正确终止 QThread?

Qt on Python 中的 QThread

如何在 QT 中停止 qThread [重复]

实现 QThread 的正确方法是啥...(请举例...)

Qt线程—QThread的使用--run和movetoThread的用法