Почему установка флага Qt :: SplashScreen предотвращает закрытие

я имею QMainWindow который вставляет QQuickWidget,
QQuickWidget отображать две разные qml (splash.qml а также main.qml) в зависимости от состояния приложения (инициализировано или нет).

Я хочу, чтобы мое окно было в заставка режим, когда 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. Затем я возвращаю флаги к их значению по умолчанию, чтобы вернуться с заставки:

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

Все идет как положено, но когда я пытаюсь закрыть свое приложение, оно никогда не достигает конца main() в то время как это близко, если я не применяю Qt::SplashScreen флаг.

Что я должен сделать, чтобы закрыть приложение?

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 установлен в false когда вы установите флаг Qt::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);
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]