当我做一些绘图工作时,Qt冻结了。我想展示“装货.”此时的消息框。我用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。功能结束后,QmessageBox就消失了。但是,使用此代码,QmessageBox将在plot()函数结束后显示。为什么是这样的行为?
我使用QT4.8.5
谢谢。
发布于 2013-11-21 07:28:20
Qt中的GUI类只能从主线程访问。
这个问题的官方解决方案是在不同的线程中完成繁重的工作,而不是让GUI冻结。有关在Qt中使用线程的不同方式,请参见https://doc.qt.io/qt-5/threads-technologies.html。
警告:,您应该向从QThread派生的类中添加槽,而不是。来自文档(https://doc.qt.io/qt-5/qthread.html):
重要的是要记住,QThread实例存在于实例化它的旧线程中,而不是在调用run()的新线程中。这意味着QThread的所有排队插槽都将在旧线程中执行。因此,希望调用新线程中的槽的开发人员必须使用worker对象方法;不应该将新的槽直接实现到子类QThread中。
这些链接适用于Qt 5,但大多数概念也适用于QT4.8。
https://stackoverflow.com/questions/20109223
复制相似问题