QThread 和 GUI 线程说明

Posted

技术标签:

【中文标题】QThread 和 GUI 线程说明【英文标题】:QThread and GUI Thread clarification 【发布时间】:2014-01-07 10:32:44 【问题描述】:

在官方 Qt 文档中:

如前所述,每个程序在启动时都有一个线程。该线程称为“主线程”(在 Qt 应用程序中也称为“GUI 线程”)。 Qt GUI 必须在这个线程中运行。所有小部件和几个相关的类,例如 QPixmap,都不能在辅助线程中工作

现在,在一个 qt 项目中,我尝试了以下代码:

QThread* thread = new QThread;
DetectList *list = new DetectList;
list->moveToThread(thread);

connect(thread, SIGNAL(started()), list, SLOT(process()));
thread->start();

其中 DetectList 是 QWidget 派生的一个类。为什么代码编译和运行? DetectList不是只能在主线程中运行吗?

【问题讨论】:

DetectList 是否显示任何 GUI 元素,或者您只是在调用进程? "为什么要编译运行代码?" -> 你的意思是你连运行时警告都没有?你能把这段代码给我们看吗? 【参考方案1】:

就像 Laszlo Papp 指出你正在接受交战,moveToThread 没有效果。战战会说:QObject::moveToThread: Widgets cannot be moved to a new thread

见source code of moveToThread。

我建议您描述一下您到底想做什么以及为什么要消除线程。我很确定有更好的解决方案(比如 Qt Concurrent)。

【讨论】:

【参考方案2】:

该程序将编译并运行,因为从 C++ 前言来看,它在语法上是正确的。

Qt 文档说,让 GUI 相关代码在与主线程不同的线程中运行是不正确的,如果发生这种情况,那么应用程序可能会在运行时崩溃。

例如,在您之前的代码中,如果 DetectList 是对象正在与某些 GUI 元素交互,那么您的程序将会崩溃:

// If the process implementation interacts with GUI elements then the application will crash
void DetectList::process()

    // a simple gui interaction
    checkBox->setChecked(true);

【讨论】:

以上是关于QThread 和 GUI 线程说明的主要内容,如果未能解决你的问题,请参考以下文章

将对象的亲和性从 QThread 更改为主 GUI 线程

QThread 与 QObject的关系(QObject可以用于多线程,可以发送信号调用存在于其他线程的slot函数,但GUI类不可重入)

Qthread 锁定 Gui PySide

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

Qthread 不工作,GUI 仍然挂起

PyQt中带有QThread的后台线程