Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么设置Qt::SplashScreen标志阻止关闭_C++_Qt_Qml_Qwindow - Fatal编程技术网

C++ 为什么设置Qt::SplashScreen标志阻止关闭

C++ 为什么设置Qt::SplashScreen标志阻止关闭,c++,qt,qml,qwindow,C++,Qt,Qml,Qwindow,我有QMainWindow,它嵌入了QQuickWidget QQuickWidget根据应用程序的状态(初始化或未初始化)显示两种不同的qml(splash.qml和main.qml) 当显示splash.qml时,我希望我的窗口处于splashScreen模式,因此我: MainWindow::MainWindow(QMainWindow * parent) :QMainWindow(parent) { QApplication::setAttribute(Qt::AA_DontCr

我有
QMainWindow
,它嵌入了
QQuickWidget

QQuickWidget
根据应用程序的状态(初始化或未初始化)显示两种不同的qml(
splash.qml
main.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将触发一个插槽。然后,我将标志重置为默认值,以从splashscreen返回:

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


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

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

通过查看
QWidget::close
,我们有以下内容(我的重点):

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

另一方面,我们为Qt::WA_QuitOnClose提供了这个:

当具有属性集的最后一个小部件已接受
closeEvent()
时,使Qt退出应用程序。可以使用
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);

尝试使用
Qt::FramelessWindowHint
而不是
Qt::SplashScreen
标志。这可能是QT中的一个错误。实际上,重新设置属性QT::WA_QuitOnClose可以解决这个问题。Thanks@grunk我很高兴知道它起作用了。我也试着让你们洞察其中的原因,以便更好地理解为什么它并没有像你们期望的那个样起作用。希望能有所帮助顺便说一句,来自qt支持部门的回复:“这是问题的原因,实际上是qt中的一个bug,因为它应该已经处理了这个问题。你可以在这里在线跟踪这个补丁”:@grunk我想值得将这个问题与Q/a联系起来。它至少有助于跟踪引擎盖下发生的事情。@grunk还注意问题的文本:如果窗口标志从一个可能关闭WA_QuitOnClose属性的类型更改,那么当更改回允许它的类型时,它应该设置回打开状态。你不能把任何东西变回去。这不是你在问题中观察到的或至少描述的。