Question

Qt GUI frozen when I did some plotting works. I want to show "loading.." message box at this time. I use QThread for this but I can not do.

my QThread class

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:

};

I wrote in my main header file

public:
    myThread *mess;
    QMessageBox box;

public slots:
    void threadSlot();

I wrote in my main cpp file:

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();
}

In my main cpp file there is a function which freeze GUI.

void Archive::plot()
{
    mess->start();

    //heavy work. It takes 2-3 second and GUI become unresponsive.

}

I want that thread starts firstly and show QmessageBox. after plot() function end, QmessageBox disappeared. But with this code QmessageBox shows after plot() function ends. Why it is behave like this?

I use Qt 4.8.5

Thanks.

Was it helpful?

Solution

GUI classes in Qt can only be accessed from the main thread.

The official solution to this problem is to do your heavy work in a different thread, and not let your GUI freeze. See https://doc.qt.io/qt-5/threads-technologies.html for different ways to use threads in Qt.

WARNING: You should NOT add slots to classes derived from QThread. From the documentation (https://doc.qt.io/qt-5/qthread.html):

It is important to remember that a QThread instance lives in the old thread that instantiated it, not in the new thread that calls run(). This means that all of QThread's queued slots will execute in the old thread. Thus, a developer who wishes to invoke slots in the new thread must use the worker-object approach; new slots should not be implemented directly into a subclassed QThread.

These links are for Qt 5, but most of the concepts apply to Qt 4.8 too.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top