当 GUI 冻结时显示带有 QThread 的 QMessageBox

Posted

技术标签:

【中文标题】当 GUI 冻结时显示带有 QThread 的 QMessageBox【英文标题】:showing QMessageBox with QThread when GUI frozen 【发布时间】:2013-11-20 23:19:49 【问题描述】:

当我进行一些绘图工作时,Qt GUI 冻结。此时我想显示“正在加载..”消息框。我为此使用 QThread,但我做不到。

我的 QThread 类

myThread.cpp

#include "myThread.h"
#include <QtCore>

myThread::myThread(QObject *parent) :
    QThread(parent)



void myThread::run()

    emit threadSignal();

myThread.h

#ifndef MYTHREAD_H
#define MYTHREAD_H

#include <QThread>

class myThread : public QThread

    Q_OBJECT
public:
    explicit myThread(QObject *parent = 0);
    void run();

signals:
    void threadSignal();

public slots:

;

我写在我的主头文件中

public:
    myThread *mess;
    QMessageBox box;

public slots:
    void threadSlot();

我在我的主 cpp 文件中写道:

Archive::Archive(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Archive)

    ui->setupUi(this);

    mess=new myThread(this);
    connect(mess, SIGNAL(threadSignal()), this, SLOT(threadSlot()));
    box.setWindowFlags(Qt::WindowStaysOnTopHint);


void Archive::threadSlot()

    box.show();

在我的主 cpp 文件中有一个冻结 GUI 的功能。

void Archive::plot()

    mess->start();

    //heavy work. It takes 2-3 second and GUI become unresponsive.


我希望该线程首先启动并显示 QmessageBox。 plot() 函数结束后,QmessageBox 消失了。但是使用此代码 QmessageBox 在 plot() 函数结束后显示。为什么会这样?

我使用 Qt 4.8.5

谢谢。

【问题讨论】:

如果所有繁重的工作都在主线程上完成,你的 myThread 对象的目的是什么? 我只想显示一个带有文本“Wait”的 QMessageBox。如果我在主线程中执行此操作 QmessageBox 在 GUI 冻结之前不会出现。 那么你应该把繁重的工作转移到你的myThread对象上,并将GUI的东西放在你的主线程中,而不是相反。 【参考方案1】:

Qt 中的 GUI 类只能从主线程访问。

这个问题的官方解决方案是在不同的线程中完成繁重的工作,而不是让你的 GUI 冻结。请参阅https://doc.qt.io/qt-5/threads-technologies.html 了解在 Qt 中使用线程的不同方式。

警告:您应该向派生自 QThread 的类添加槽。来自文档(https://doc.qt.io/qt-5/qthread.html):

重要的是要记住 QThread 实例存在于旧的 实例化它的线程,而不是在调用 run() 的新线程中。 这意味着 QThread 的所有排队槽都将在旧的 线。因此,希望在新线程中调用槽的开发人员 必须使用工作对象方法;新插槽不应该 直接在子类 QThread 中实现。

这些链接适用于 Qt 5,但大多数概念也适用于 Qt 4.8。

【讨论】:

以上是关于当 GUI 冻结时显示带有 QThread 的 QMessageBox的主要内容,如果未能解决你的问题,请参考以下文章

QT QThread::isrunning 冻结程序在 Pi

在qthread中停止长时间运行的进程

Qthread 锁定 Gui PySide

发生单击时显示和隐藏GUI的最佳方法

带有 Gui 的 Websocket

即使使用 QThread,QT 程序也会停止