я имею 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
флаг.
Что я должен сделать, чтобы закрыть приложение?
Прежде всего, давайте попробуем понять, почему это не работает так, как вы ожидаете.
Глядя на документация из 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);
Других решений пока нет …