QDialog本身就关闭了,我该如何修复?

时间:2019-10-26 15:01:59

标签: c++ qt qdialog

我的班级名称就像(做什么)_(类型),例如:reg_QDialog

这里是执行中的dlg的代码,如果被接受,则创建QMainWindow:

if(log_dlg->exec() == QDialog::Accepted)
{
    find_wnd = new find_QMainWindow();
    find_wnd->show();
}

log_dlg有2个btns:“ Enter”(这是接受结果)和“ Reg”(打开新的dlg)

“ Enter”和“ Reg”代码在此处:

void log_QDialog::on_btn_enter_clicked()
{
    this->accept();
}

void log_QDialog::on_btn_reg_clicked()
{
    reg_QDialog *reg_dlg = new reg_QDialog();

    this->hide();
    if(reg_wnd->exec() == QDialog::Accepted)
    {
        //code
    }
    this->show();
}

所以,这是问题所在:

Step by step:
1) run the prog    //it starts with dlg_log 
2) "Reg"           //creating dlg_reg 
3) accept dlg_reg  //returning to dlg_log 
4) "Enter"         //trying to create QMainWindow 
QMainWindow is not created, and the app just closed

从reg_dlg中“返回”(实际上只是隐藏然后显示),然后将btn与accept结果一起推送后,它什么都不做!它只是关闭了程序,但必须显示QMainWindow!

main.cpp的所有真实代码:

#include "log_window_root.h"
#include "find_mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    log_window_root * log_wnd;
    find_mainwindow * find_wnd;

    log_wnd = new log_window_root();
    log_wnd->setWindowFlags(Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint);
    log_wnd->setModal(true);

    if(log_wnd->exec() == QDialog::Accepted)
    {
        find_wnd = new find_mainwindow();
        find_wnd->setWindowFlags(Qt::MSWindowsFixedSizeDialogHint);
        find_wnd->show();
    }
    return a.exec();
}

3 个答案:

答案 0 :(得分:0)

当最后一个窗口关闭时,QApplication退出并关闭。 您可以通过将 QApplication::quitOnLastWindowClosed 属性设置为false来放弃此设置。

    QApplication a(argc, argv);
    a.setQuitOnLastWindowClosed(false);

使用这些对话框完成工作后,您可能希望将其恢复为以前的状态。

正如@Jens在问题的另一个答案中提到的那样,这将在某些时候中断evenloop,甚至在调用a.exec()之前QApplication都会退出。因此,您还可以创建宽度/高度为零或屏幕外的QWidget作为对话框的父级。 QSplashScreen也是一个很好的选择。您的所有对话框都应该是您的初始屏幕子级。最后,您可以调用QSplashScreen::finish来完成初始屏幕。

答案 1 :(得分:0)

您的操作超出了Qt的限制。查看文档:

  

通常,在调用exec()之前无法进行任何用户交互。   作为一种特殊情况,可以在使用诸如QMessageBox之类的模式小部件之前   调用exec(),因为模式小部件调用exec()以启动本地   事件循环。

在Mac OS上测试代码将给您可怕的警告

  

modalSession已提前退出-检查重入呼叫   到endModalSession

这表明您正在努力工作,并且代码随时都会中断。

考虑重新编写代码,以便MainWindow出现,然后显示对话框。如果要继续执行Dialog序列,请从on_btn_reg_clicked中删除hide()/ show()对(这些调用会弄乱事件循环)。

答案 2 :(得分:0)

[从duplicate-closed问题重新发布,因为其顶部的横幅可能会导致人们完全跳过该问题,恕我直言,这个问题的答案不好。]

这是一个非常简单的示例,显示在QMainWindow之前的对话框。该对话框仅显示是否启动主应用程序的选项。它们的关键点是QDialog部分发生在创建任何其他小部件之前(例如此处的QMainWindow),并且如果需要,应用程序(main())将在此之前退出。使用完QDialog后,没有理由保留它,因此我在堆栈上创建它,然后delete创建它。


int main(int argc, char *argv[])
{
  QApplication a(argc, argv);
  QDialog *d = new QDialog();
  QPushButton *pbYes = new QPushButton("Would you like to play a game?", d);
  QPushButton *pbNo = new QPushButton("Get me out of here!", d);
  QObject::connect(pbYes, &QPushButton::clicked, [d]() { d->done(QDialog::Accepted); });
  QObject::connect(pbNo, &QPushButton::clicked, [d]() { d->done(QDialog::Rejected); });

  d->setLayout(new QVBoxLayout);
  d->layout()->addWidget(pbYes);
  d->layout()->addWidget(pbNo);

  const int ret = d->exec();
  delete d;

  if (ret == QDialog::Rejected)
    return 0;

  QMainWindow mw;
  mw.setCentralWidget(new QLabel("Welcome to the Game!", &mw));
  mw.show();

  return a.exec();
}