我有嵌入QQuickWidget
的QMainWindow
。QQuickWidget
显示两个不同的qml (splash.qml
和main.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);