隐藏QMainWindow存在问题:在显示QMessageBox后应用程序崩溃

8
// 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);

当我需要时,我使用 a.exit(0) 终止应用程序。但我仍然不明白出了什么问题。
是的!看起来我懂得出了什么问题。这是关于方法 QApplication::quitOnLastWindowClosed(bool) 的信息:
此属性表示当最后一个窗口关闭时应用程序是否隐式退出。默认值为 true。如果此属性为 true,则在关闭具有 Qt::WA_QuitOnClose 属性设置的最后一个可见主窗口(即没有父窗口的窗口)时,应用程序将退出。默认情况下,该属性对除子窗口以外的所有小部件都设置。请参阅 Qt::WindowType 以获取 Qt::Window 对象的详细列表。
在 QMainWindow 隐藏后,就没有可见的窗口了。当 QMessageBox 关闭时,应用程序退出。
3个回答

3
问题似乎是这样的:当对话框关闭时,应用程序认为没有窗口处于打开状态(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;
}

或者,您可以将应用程序设置为窗口的父级


很遗憾,您无法将应用程序设置为MainWindow的父级,因为父子关系要求父级是QWidget的后代;QApplication来自QObject而不是QWidget。 - spbots

3

我不确定,但是我认为当QMessageBox关闭时,它试图将焦点返回到它的父窗口(您的MainWindow),但该窗口已被隐藏。此操作失败,系统会抛出异常。


1
尝试这个函数:void MainWindow::showMessageBox() { QMessageBox::information(this, "Hello,", "world!", QMessageBox::Ok); this->show(); }不设置a.setQuitOnLastWindowClosed(false);如果它不崩溃 - 这意味着它无法将焦点返回到MainWindow并抛出异常。 - firescreamer
this替换为NULL并传递给QMessageBox::information(...)。消息框现在没有父窗口,但应用程序会终止。 - Andrey Moiseev
我重新实现了 focusInEvent - QMessageBox 不再尝试返回焦点。 - Andrey Moiseev

2
只需尝试以下步骤-将此内容放入:

...
app.setQuitOnLastWindowClosed(false);
...

致您:

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

这应该会有所帮助!


太好了!解决了我的问题,谢谢! - Yuanhui

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接