【问题标题】:Why Setting Qt::SplashScreen flag prevent closing为什么设置 Qt::SplashScreen 标志会阻止关闭
【发布时间】:2016-11-03 15:56:13
【问题描述】:

我有 QMainWindow,其中嵌入了 QQuickWidget
QQuickWidget 根据应用的状态(初始化与否)显示两个不同的 qml(splash.qmlmain.qml)。

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

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 会触发一个槽。然后我将标志重置为默认值以从启动画面返回:

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

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

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

【问题讨论】:

  • 尝试使用Qt::FramelessWindowHint 而不是Qt::SplashScreen 标志。这可能是 QT 中的一个错误。

标签: c++ qt qml qwindow


【解决方案1】:

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

通过查看QWidget::closedocumentation,我们有以下信息(重点是我的):

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

另一方面,我们为Qt::WA_QuitOnClose 准备了这个:

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

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

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

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

    李>
  • HereadjustQuitOnCloseAttribute 的实际实现,会发生这种情况:

    // ...
    
    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 的错误,它是(非常糟糕的)记录在案的预期行为。


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

可能,只需按正确的顺序设置正确的标志和属性即可解决此问题。
我不确定,但你可以试一试:

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

【讨论】:

  • 确实,将属性 Qt::WA_QuitOnClose 重新设置为 true 即可解决问题。谢谢
  • @grunk 我很高兴知道它有效。我还试图让您深入了解原因,以更好地理解为什么它没有按您的预期工作。希望它有所帮助。 ;-)
  • 顺便说一句,来自 qt 支持的响应:“这是问题的原因,它实际上是 Qt 中的一个错误,因为它应该已经处理了这个问题。你可以在这里在线跟踪这个补丁”:@987654324 @
  • @grunk 我想值得将此 Q/A 与问题联系起来。这至少有助于追踪幕后发生的事情。
  • @grunk 还要注意问题的文本:如果窗口标志从一种类型更改为会关闭 WA_QuitOnClose 属性,那么在更改回允许它的类型。你没有_改变任何东西。这不是您观察到的,或者至少不是问题中描述的。
猜你喜欢
  • 2014-06-20
  • 2011-04-03
  • 2015-02-17
  • 2014-04-17
  • 2020-12-22
  • 1970-01-01
  • 2014-09-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多