[Interest] Strange problem where exec() of dialogs returns immediately

Thiago Macieira thiago.macieira at intel.com
Sun Mar 11 18:09:32 CET 2012


On domingo, 11 de março de 2012 18.45.50, Nikos Chantziaras wrote:
> On 11/03/12 18:33, Thiago Macieira wrote:
> > On domingo, 11 de março de 2012 18.25.58, Nikos Chantziaras wrote:
> >>> But it is the creation of that message box that causes the problem,
> >>> right?
> >>> Try removing the message box and you'll see it works again.
> >> 
> >> Of course if I remove the message box the bug doesn't trigger, because
> >> the point of this is that exec() returns immediately.  If I remove the
> >> message box, there's no call to exec().
> >> 
> >> I'm reporting a problem with exec(), not the absence of one when not
> >> using exec()
> > 
> > It looks like you forgot to accept the close event and pass it to the
> > QMainWindow class. It will not close unless you let it close.
> 
> I suspect that you didn't look at the code.

And I suspect you didn't read my reply.

void MainWindow::closeEvent(QCloseEvent* e)
{
    QMessageBox* msgBox = new QMessageBox(QMessageBox::Question,
                                          "Quit",
                                          "Quit the application?",
                                          QMessageBox::Yes | 
QMessageBox::Cancel, this);
    msgBox->setDefaultButton(QMessageBox::Cancel);

    if (msgBox->exec() == QMessageBox::Yes) {
        qDebug() << "Yes";
        exit(0);
    } else {
        qDebug() << "Cancel";
        e->ignore();
    }
}

I don't see e->accept() or QMainWindow::closeEvent(e).

If that msgBox->exec() returns immediately, it's because the event loop is 
already exiting. You cannot loop again while the quit flag is active. 

You connected the lastWindowClosed() signal to the application's quit() slot, 
so my guess is that somehow the last window *was* closed, the signal emitted, 
the event loop started to quit, which means you can't open any more dialogs.

Which begs the question: which window was closed? It seems impossible that 
it's the main window, because we're inside its closeEvent. Looking at your 
code again, we see this:

void Application::main()
{
    QFileDialog::getOpenFileName(0, "TEST", "", "All files (*)");
    this->fMainWin->show();
    while (true) {
        qApp->processEvents(QEventLoop::WaitForMoreEvents | 
QEventLoop::AllEvents);
    }
}

Note how you open and *close* a window before showing the main window. That 
means the lastWindowClosed() signal got emitted. You can't start new event 
loops now until this event loop comes out of app->exec().

Note how even you had to force an event loop by that horrible while (true) 
construct. Remove it completely. Once you solve the problem of the last window 
closing too soon, the main event loop will take care of the main window's 
lifetime.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center
     Intel Sweden AB - Registration Number: 556189-6027
     Knarrarnäsgatan 15, 164 40 Kista, Stockholm, Sweden
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 190 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20120311/078b8d5a/attachment.sig>


More information about the Interest mailing list