为什么设置Qt::SplashScreen标志防止关闭



我有嵌入QQuickWidgetQMainWindow
QQuickWidget显示两个不同的qml (splash.qmlmain.qml)根据应用程序的状态(初始化或未初始化)。

我希望我的窗口是在splashScreen模式时,splash.qml显示,所以我做了:

MainWindow::MainWindow(QMainWindow * parent) :QMainWindow(parent)
{
    QApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
    mDefaultFlags = windowFlags();
    setAttribute(Qt::WA_DeleteOnClose, true);
    setWindowFlags(Qt::SplashScreen);
    mQuickWidget = new QQuickWidget(this);
    //...
    setCentralWidget(mQuickWidget);
    mQuickWidget->show();
}

当init完成并加载另一个QML文件时,QML触发一个槽。然后,我将标志重置为其默认值,以从splashscreen返回:

void MainWindow::UpdateWindowAfterInit()
{
    setWindowFlags(mDefaultFlags);
    show();
}

一切都如预期的那样,但是当我试图关闭我的应用程序时,它永远不会到达main()的末尾,而如果我不应用Qt::SplashScreen标志,它会很好地关闭。

我应该怎么做才能关闭我的应用程序

首先,让我们试着理解为什么它不像你期望的那样工作。

通过查看QWidget::close的文档,我们有以下(强调我的):

QApplication::lastWindowClosed()信号在最后一个具有Qt::WA_QuitOnClose 属性集的可见主窗口(即没有父窗口)关闭时发出。默认情况下,此属性为所有小部件设置,除了瞬态窗口,如闪屏,工具窗口和弹出菜单。

另一边是Qt::WA_QuitOnClose:

使Qt在最后一个具有属性集的小部件接受closeEvent()时退出应用程序。此行为可以通过QApplication::quitOnLastWindowClosed属性进行修改。默认情况下,为所有类型为Qt::Window的小部件设置此属性。

因此,怀疑是您设置或您认为已设置的属性实际上在更改标志时被重置。

通过查看代码,我们有以下内容:

  • 下面是setWindowFlags的实际实现。您可以看到,如果旧类型是窗口(也就是说,如果您设置了Qt::Window标志,这就是您的情况),则调用adjustQuitOnCloseAttribute函数。

  • 这是adjustQuitOnCloseAttribute的实际实现,这发生了:

    // ...
    if (type != Qt::Widget && type != Qt::Window && type != Qt::Dialog)
        q->setAttribute(Qt::WA_QuitOnClose, false);
    // ...
    

    这意味着当设置标志Qt::SplashScreen时,属性Qt::WA_QuitOnClose被设置为false

最后,我们有以下Qt::WA_DeleteOnClose:

使Qt在小部件接受关闭事件时删除该小部件(参见QWidget::closeEvent())。

因为你没有Qt::WA_QuitOnClose设置,窗口不再接受close事件,它不会被销毁。

更重要的是,它不是关闭的,这是您在应用程序中观察到的。这不是Qt的一个bug,它是一个(相当糟糕的)被记录的预期行为。


现在,我们可以试着找出解决这个问题的方法。

也许,用正确的顺序设置正确的标志和属性就足够了。
我不确定,但你可以试一试:

setWindowFlags(Qt::SplashScreen);
setAttribute(Qt::WA_QuitOnClose, true);
setAttribute(Qt::WA_DeleteOnClose, true);

相关内容

  • 没有找到相关文章

最新更新