GUI冻结时显示QMessageBox和QThread

时间:2013-11-20 23:19:50

标签: c++ qt qt4 qthread

当我做一些绘图工作时,Qt GUI被冻结了。我想在此时显示“loading ..”消息框。我使用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

感谢。

1 个答案:

答案 0 :(得分:3)

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

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

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

  

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

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