QDialog closing on it's own, how can i fix it?

旧时模样 提交于 2020-01-11 12:10:10

问题


My class names is like (what it does)_(type) for example: reg_QDialog

Here is code of an executing dlg and if Accepted creating QMainWindow:

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

log_dlg has 2 btns: "Enter" (here is the accept result) and "Reg" (opens a new dlg)

"Enter" and "Reg" code is here:

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

So, here is the problem:

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

After "returning"(it's, actually, just hiding and then showing) from the reg_dlg and pushing btn with accept result it does nothing! It just closes the programm, but it had to show QMainWindow!

All real code of 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();
}

回答1:


You are a operating a bit beyond the limits of Qt. Looking at the documentation:

Generally, no user interaction can take place before calling exec(). As a special case, modal widgets like QMessageBox can be used before calling exec(), because modal widgets call exec() to start a local event loop.

Testing your code on Mac OS will give you the dreaded warning

modalSession has been exited prematurely - check for a reentrant call to endModalSession

which shows, that you are working on thin ice and your code will break any time.

Consider reworking your code so that the MainWindow comes up and then show your dialogs. If you want to go on with the Dialog sequence, then remove the hide()/show() pair from on_btn_reg_clicked (these calls mess up your event loops).




回答2:


QApplication exits and close when the last window has been closed. You can discard this by setting QApplication::quitOnLastWindowClosed property to false.

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

You may want to revert it to it's previous state when your job is done with those dialogs.

As @Jens mentioned in the other answer to your question, this is will break evenloop at some point and QApplication exits before even a.exec() being called. So, you can also create a zero width/height or off-screen QWidget as a parent of your dialogs. A QSplashScreen is also a good candidate for this. All your dialogs should be your splash screen children. At last, you can finish your splash screen by calling QSplashScreen::finish.




回答3:


[Re-posting from duplicate-closed question since the top banner on it may cause people to skip that question entirely, and IMHO this one doesn't have a good answer.]

Here's a very simple example of showing a dialog before a QMainWindow. The dialog simply presents the option of starting the main app or not. They key points are that the QDialog portion happens before any other widgets are created (eg. QMainWindow here), and the app (main()) exits before that if needed. No reason to keep the QDialog around after it is used, so I create it on the stack and delete afterwards.


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


来源:https://stackoverflow.com/questions/58571952/qdialog-closing-on-its-own-how-can-i-fix-it

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!