Reputation: 79
My goal is to open a dialog box. When the user clicks on OK, it will open the same dialog box in a loop. This means that opening the dialog box must be blocking the next opening. I not able to pass the second loop iteration and I have a runtime failure for some reason I do not understand.
Here are the complete file contents that can be directly imported into Qt Creator serving as a minimal reproducible example. The main function is defined in main.cpp
as:
#include <QApplication>
#include <QObject>
#include <cstdio>
#include "MyClass.h"
int main(int argc, char *argv[])
{
MyClass obj;
QApplication a(argc, argv);
obj.Init(&a);
obj.start();
return a.exec();
}
Here is the content of the MyClass class MyClass.cpp
:
#include "MyClass.h"
MyClass::MyClass() { }
void MyClass::openDialog()
{
// Create and execute the dialog box
QMessageBox messageBox;
messageBox.setText("Dialog Box");
messageBox.exec();
// Signal that the dialog box has closed
emit dialogClosed();
}
void MyClass::run() {
while (1){
printf("PRESS OK TO CONTINUE LOOPING...\n");
// Open dialog box within the GUI thread
QMetaObject::invokeMethod(this, "openDialog", Qt::QueuedConnection);
// Wait for dialog to close
QEventLoop loop;
connect(this, &MyClass::dialogClosed, &loop, &QEventLoop::quit);
loop.exec();
printf("LOOP ENDED.\n");
}
}
int MyClass::Init(QCoreApplication * App)
{
}
Here is the header MyClass.h
:
#include <QThread>
#include <QCoreApplication>
#include <QMessageBox>
#ifndef MYCLASS_H
#define MYCLASS_H
class MyClass : public QThread
{
Q_OBJECT
private:
void run();
signals:
void dialogClosed();
public:
MyClass();
int Init(QCoreApplication *App);
public slots:
void openDialog();
};
#endif // MYCLASS_H
And finally this is the Qt Project file MyClass.pro
:
QT += core network
QT += widgets
CONFIG += c++11
SOURCES += main.cpp MyClass.cpp
HEADERS += MyClass.h
When running, only the first dialog box opening succeeds and then none opens. I get the following terminal output:
QThread: Destroyed while thread is still running
Upvotes: 1
Views: 89
Reputation: 2963
You have to call QEventLoop::exit
in order to terminate the event loop. Because this function takes an integer argument, you have to connect a signal with a matching argument, due to the way signals and slots work. Otherwise, you can connect the signal to a lambda function like so:
connect(this, &MyClass::dialogClosed, [&loop]{ loop.exit(); });
Upvotes: 0