отображение QMessageBox с QThread при зависании графического интерфейса

Графический интерфейс 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 есть функция, которая замораживает графический интерфейс.

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

Спасибо.


person user4757345    schedule 20.11.2013    source источник
comment
Какова цель вашего объекта myThread, если вся тяжелая работа выполняется в основном потоке?   -  person thuga    schedule 21.11.2013
comment
Я просто хочу показать QMessageBox с текстом Подождите. Если бы я сделал это в основном потоке, QmessageBox не появлялся бы до зависания графического интерфейса.   -  person user4757345    schedule 21.11.2013
comment
Затем вы должны перенести тяжелую работу на свой объект myThread и оставить материал GUI в своем основном потоке, а не наоборот.   -  person thuga    schedule 21.11.2013


Ответы (1)


Доступ к классам 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.

person JKSH    schedule 21.11.2013