Hai Nguyen Van
Hai Nguyen Van

Reputation: 79

Cannot make a loop of opening dialog boxes in Qt

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.

enter image description here

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

Answers (1)

sigma
sigma

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

Related Questions