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
Благодарю.
Классы GUI в Qt могут быть доступны только из основного потока.
Официальное решение этой проблемы - сделать вашу тяжелую работу в другом потоке и не позволить вашему графическому интерфейсу замораживаться. См. 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.
myThread
если вся основная работа выполняется в основном потоке?