Проблема со скрытым QMainWindow: сбой приложения после отображения QMessageBox

// main.cpp

#include <QApplication>

#include "mainwindow.h"

int main(int argc, char* argv[])
{
    QApplication app(argc, argv);
    MainWindow* window = new MainWindow();
    window->show();
    return app.exec();
}

// mainwindow.cpp

#include <QTimer>
#include <QMessageBox>
#include <iostream>

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    this->setCentralWidget(new QWidget());
}

void MainWindow::mousePressEvent(QMouseEvent* event)
{
    this->hide();
    QTimer* timer = new QTimer();
    timer->setInterval(3*1000);
    timer->start();
    connect(timer, SIGNAL(timeout()), this, SLOT(showMessageBox()));
}

void MainWindow::showMessageBox()
{
    QMessageBox::information(this, "Hello,", "world!", QMessageBox::Ok);
}

MainWindow::~MainWindow()
{
    std::cerr << "Destructor called" << std::endl;
}

Я нажимаю на окно-оно скрывается, и появляется QMessageBox. Я нажимаю " ОК " - приложение завершается, и деструктор MainWindow не вызывается. Почему приложение прекращается? Может, я что-то пропустил? Qt 4.7.0, Linux.

... Упс! Похоже, я нашел то, что мне нужно.

a.setQuitOnLastWindowClosed(false);

когда мне это нужно, я прекращаю приложение с помощью.выход (0). Но я все еще не понимаю, что было не так.

да! Похоже, я понимаю, что было неправильный. это информация о методе

QApplication::quitOnLastWindowClosed(bool):

это свойство содержит ли приложение неявно завершает работу при закрытии последнего окна. Значение по умолчанию-true. Если это свойство имеет значение true,приложения уходит когда последний видимого первичный окно (т. е. окно без родителя) с набором атрибутов Qt::WA_QuitOnClose закрывается. По умолчанию этот атрибут задан для всех виджетов, кроме суб-окна. См.Qt::WindowType для получения подробного списка объектов Qt::Window.

после того, как QMainWindow скрыт, нет видимого окна. Когда QMessageBox закрыт, выход из приложения.

2 ответов


проблема выглядит следующим образом: когда диалоговое окно закрыто, приложение думает, что больше нет открытых окон (setQuitOnLastWindowClosed относится к видимым окнам верхнего уровня), поэтому он завершает работу. Деструктор вашего окна не вызывается, потому что вы никогда не удаляете объект!

Это должно распечатать сообщение:

int main(int argc, char* argv[])
{
  QApplication app(argc, argv);
  MainWindow* window = new MainWindow();
  window->show();
  int ret = app.exec();
  delete window;
  return ret;
}

в качестве альтернативы вы можете установить приложение в качестве родителя окна


Я не уверен, но я думаю, что когда QMessageBox закрылся, он пытается вернуть фокус своему родителю (вашему главному окну), ведьма скрыта. Эта операция завершается неудачно, и система выдает исключение.