1

我有QMainWindow哪个嵌入了QQuickWidget.
根据应用程序的状态(初始化或未初始化)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();
}

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

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

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

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

4

1 回答 1

1

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

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

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

另一方面,我们有这个Qt::WA_QuitOnClose

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

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

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

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

  • 是实际的实现,adjustQuitOnCloseAttribute会发生这种情况:

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

    这意味着当您设置标志时,该属性Qt::WA_QuitOnClose被设置为。falseQt::SplashScreen

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

当小部件接受关闭事件时,使 Qt 删除该小部件(请参阅 参考资料QWidget::closeEvent())。

因为您不再拥有该Qt::WA_QuitOnClose集合,所以窗口不再接受该close事件并且它不会被销毁。

更重要的是,它没有关闭,这是您在应用程序中观察到的。这不是 Qt 的错误,它是(非常糟糕的)记录在案的预期行为。


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

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

setWindowFlags(Qt::SplashScreen);
setAttribute(Qt::WA_QuitOnClose, true);
setAttribute(Qt::WA_DeleteOnClose, true);
于 2016-11-12T18:55:53.463 回答