在 Qt GUI 事件线程中检测到“我正在运行”

Posted

技术标签:

【中文标题】在 Qt GUI 事件线程中检测到“我正在运行”【英文标题】:Detect that "I'm running" in Qt GUI event thread 【发布时间】:2016-01-26 16:24:41 【问题描述】:

我有这个功能来更新一些 GUI 的东西:

void SavedConnections::renderList()

  // Do GUI stuff! Must run in Qt thread!!!
    ...

我需要确保不会从其他线程调用此函数。我打算做的是将其推迟到事件循环中并发出警告:

void SavedConnections::renderList()
 
  if(!this_thread_is_Qt_GUI_thread()) 
    qDebug()<< "Warning: GUI operation attempted from non GUI thread!\n";
    QCoreApplication::postEvent(this, new UpdateGUIEvent());
    return;
  
  // Do GUI stuff! Must run in Qt thread!!!
    ...

这种模式也非常方便地制作保证在 GUI 线程中异步运行的方法,而没有任何难看的语法。 I already asked similar question about Java's ExecutorService.

【问题讨论】:

我不会认为这是 the question it was marked as such 的副本。好吧,从技术上讲,它是 2016 年,另一个问题是 2009 年(Qt 4),其中主线程是 GUI 线程。今天,在 Qt 5 中,情况不再如此,因此该解决方案在这里不会奏效。 【参考方案1】:

您可以检查当前线程是否是您的对象所在的线程:

if (QThread::currentThread() != this->thread()) 
   // Called from different thread

请注意,这可能不是主要的 GUI 线程!它是this 所在的线程(参见QObject Thread affinity)。如果您不使用QObject::moveToThread 更改它,它就是创建对象的线程。

这也是QCoreApplication::postEvent 用来确定应该将事件发布到哪个线程的内容。目标线程必须运行QEventLoop 才能响应事件。

因此检查主 GUI 线程 (qApp-&gt;thread()),但如果您的对象不在主 GUI 线程中,则发布到 this 的线程可能不起作用。但是,如果你在那里做 GUI 的东西,它无论如何都应该存在于 GUI 线程中

【讨论】:

以上是关于在 Qt GUI 事件线程中检测到“我正在运行”的主要内容,如果未能解决你的问题,请参考以下文章

用事件队列解决GUI的操作顺序问题(Qt中处理方法)

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

用事件队列解决QT GUI的操作顺序问题

Qt学习笔记8.Qt中的多线程

使用 Qt Gui 执行慢速实时视频源的 Opencv 人脸检测

Python Qt GUI设计:QTimer计时器类QThread多线程类和事件处理类(基础篇—8)