我的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
感谢。
答案 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。