c++ 无法在Qt中循环打开对话框

nfzehxib  于 2023-06-25  发布在  其他
关注(0)|答案(1)|浏览(176)

我的目标是打开一个对话框。当用户单击OK时,它将循环打开同一个对话框。这意味着打开对话框必须阻止下一个打开。我无法通过第二次循环迭代,并且由于某些我不理解的原因,运行时失败。

这里是完整的文件内容,可以直接导入到Qt Creator中,作为一个最小的可复制示例。主函数在main.cpp中定义为:

  1. #include <QApplication>
  2. #include <QObject>
  3. #include <cstdio>
  4. #include "MyClass.h"
  5. int main(int argc, char *argv[])
  6. {
  7. MyClass obj;
  8. QApplication a(argc, argv);
  9. obj.Init(&a);
  10. obj.start();
  11. return a.exec();
  12. }

以下是MyClass类MyClass.cpp的内容:

  1. #include "MyClass.h"
  2. MyClass::MyClass() { }
  3. void MyClass::openDialog()
  4. {
  5. // Create and execute the dialog box
  6. QMessageBox messageBox;
  7. messageBox.setText("Dialog Box");
  8. messageBox.exec();
  9. // Signal that the dialog box has closed
  10. emit dialogClosed();
  11. }
  12. void MyClass::run() {
  13. while (1){
  14. printf("PRESS OK TO CONTINUE LOOPING...\n");
  15. // Open dialog box within the GUI thread
  16. QMetaObject::invokeMethod(this, "openDialog", Qt::QueuedConnection);
  17. // Wait for dialog to close
  18. QEventLoop loop;
  19. connect(this, &MyClass::dialogClosed, &loop, &QEventLoop::quit);
  20. loop.exec();
  21. printf("LOOP ENDED.\n");
  22. }
  23. }
  24. int MyClass::Init(QCoreApplication * App)
  25. {
  26. }

下面是头文件MyClass.h

  1. #include <QThread>
  2. #include <QCoreApplication>
  3. #include <QMessageBox>
  4. #ifndef MYCLASS_H
  5. #define MYCLASS_H
  6. class MyClass : public QThread
  7. {
  8. Q_OBJECT
  9. private:
  10. void run();
  11. signals:
  12. void dialogClosed();
  13. public:
  14. MyClass();
  15. int Init(QCoreApplication *App);
  16. public slots:
  17. void openDialog();
  18. };
  19. #endif // MYCLASS_H

最后是Qt项目文件MyClass.pro

  1. QT += core network
  2. QT += widgets
  3. CONFIG += c++11
  4. SOURCES += main.cpp MyClass.cpp
  5. HEADERS += MyClass.h

运行时,仅成功打开第一个对话框,然后不打开任何对话框。我得到以下终端输出:

  1. QThread: Destroyed while thread is still running
k4ymrczo

k4ymrczo1#

你必须调用QEventLoop::exit来终止事件循环。因为这个函数接受一个整数参数,所以由于信号和槽的工作方式,您必须将一个信号与一个匹配的参数连接起来。否则,你可以像这样将信号连接到lambda函数:

  1. connect(this, &MyClass::dialogClosed, [&loop]{ loop.exit(); });

相关问题