1

I have QMainWindow which embed a QQuickWidget.
The QQuickWidget display two differents qml (splash.qml and main.qml) according to the state of the app (initialized or not).

I want my window to be in splashScreen mode when the splash.qml is displayed, so I did :

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();
}

The QML trigger a slot when the init is done and the other qml file is loaded. I then reset the flags to their default value to go back from splashscreen :

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

Everything goes as expected , but when I try to close my app it never reach the end of the main() whereas it close nicely if i don't apply the Qt::SplashScreen flag.

What should I do to be able to close my app ?

skypjack
  • 49,335
  • 19
  • 95
  • 187
grunk
  • 14,718
  • 15
  • 67
  • 108
  • 1
    Try using `Qt::FramelessWindowHint` instead of the `Qt::SplashScreen` flag. This might be a bug in QT. – Steeve Nov 10 '16 at 08:59

1 Answers1

3

First of all, let's try to understand why it doesn't work as you expect.

By looking at the documentation of QWidget::close, we have the following (emphasis mine):

The QApplication::lastWindowClosed() signal is emitted when the last visible primary window (i.e. window with no parent) with the Qt::WA_QuitOnClose attribute set is closed. By default this attribute is set for all widgets except transient windows such as splash screens, tool windows, and popup menus.

On the other side, we have this for Qt::WA_QuitOnClose:

Makes Qt quit the application when the last widget with the attribute set has accepted closeEvent(). This behavior can be modified with the QApplication::quitOnLastWindowClosed property. By default this attribute is set for all widgets of type Qt::Window.

Therefore the suspect is that attributes you set or you think are set are actually reset when you change the flags.

By looking at the code, we have the following:

  • Here is the actual implementation of setWindowFlags. You can see that the function adjustQuitOnCloseAttribute is invoked if the old type was a window (that is, if you had the Qt::Window flag set and that's your case).

  • Here is the actual implementation of adjustQuitOnCloseAttribute and this happens:

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

    This means that attribute Qt::WA_QuitOnClose is set to false when you set the flag Qt::SplashScreen.

Finally, we have the following for Qt::WA_DeleteOnClose:

Makes Qt delete this widget when the widget has accepted the close event (see QWidget::closeEvent()).

For you don't have anymore the Qt::WA_QuitOnClose set, the window no longer accepts the close event and it is not destroyed.

More important, it is not closed, that is what you are observing in your application. This is not a bug of Qt, it is a (quite badly) documented intended behavior.


Now, we can try to figure what to do to solve the problem.

Probably, it's suffice to set the right flags and attributes in the right order to work around it.
I'm not sure about that, but you can give it a try:

setWindowFlags(Qt::SplashScreen);
setAttribute(Qt::WA_QuitOnClose, true);
setAttribute(Qt::WA_DeleteOnClose, true);
skypjack
  • 49,335
  • 19
  • 95
  • 187
  • Indeed , re setting the attribute Qt::WA_QuitOnClose to true solve the problem. Thanks – grunk Nov 14 '16 at 09:47
  • @grunk I'm glad to know that it works. I tried to give you also in insight of the reasons, to better understand why it didn't work as you expected. Hoping it helped. ;-) – skypjack Nov 14 '16 at 11:05
  • Btw response from the qt support : "This is the cause of the problem and it is actually a bug in Qt since it should have handled this already. You can track this patch online here": https://codereview.qt-project.org/176665 – grunk Nov 15 '16 at 14:30
  • @grunk I guess it's worth linking this Q/A to the issue. It would help tracking down what's happening under the hood at least. – skypjack Nov 15 '16 at 15:46
  • @grunk Note also the text of the issue: _If the window flags change from a type that would have turned off the WA_QuitOnClose attribute then it should be set back to be on when changing back to a type that allows it_. You are not _changing back anything. This is not what you observed or, at least, described in the question. – skypjack Nov 15 '16 at 19:19
  • I'm changing back when i revert to mDefaultFlags. My window have "standards" flags , i switch to splashscreen then come back to original flags. – grunk Nov 16 '16 at 07:35