Как обнаружить выключение или выход Windows в Qt
Я портирую приложение Linux на Windows, написанное на Qt. Приложение должно сохранить некоторые настройки перед закрытием. В Linux мы можем сделать это обработчиками сигналов для SIGTERM и т. д. Как я могу реализовать то же самое в Windows.
5 ответов
Если вы используете цикл событий Qt, вы можете поймать следующий сигнал:
void QCoreApplication::aboutToQuit() [сигнал]
этот сигнал посылается, когда приложение собирается выйти из основного цикла событий, например, когда цикл обработки событий падает до нуля. Это может произойти либо после вызова quit () из приложения, либо когда пользователи завершают весь сеанс рабочего стола. Сигнал особенно полезен, если ваше приложение должно сделай последнюю уборку. Обратите внимание, что в этом состоянии взаимодействие с пользователем невозможно.
кроме этого, вы можете искать следующие сообщения ниже, если вышеупомянутые сигнал не подходит для вашего варианта использования:
WM_QUIT: http://msdn.microsoft.com/en-us/library/windows/desktop/ms632641(v=vs. 85).aspx
WM_CLOSE: http://msdn.microsoft.com/en-us/library/windows/desktop/ms632617(v=vs. 85).aspx
WM_QUERYENDSESSION:http://msdn.microsoft.com/en-US/library/windows/desktop/aa376890.aspx
WM_ENDSESSION:http://msdn.microsoft.com/en-US/library/windows/desktop/aa376889.aspx
Я думаю, что другие ответы полностью упустить момент: когда вы принудительно заканчиваете приложение, это похоже на SIGKILL в Unix. нет никакого способа справиться с этим-кроме как раньше времени. что я имею в виду, обрабатывая его раньше времени, убедитесь, что вы сохраняете настройки каждый раз, когда они изменяются. Конечно, вы можете оптимизировать это поведение, например, сохранять настройки каждые несколько секунд, если они загрязнены, если вы хотите минимизировать количество дисков доступ (подумайте о потреблении энергии на мобильных устройствах).
многое из этого обрабатывается QSettings
для вас. Пока вы используете QSettings
, вы получите разумное поведение. Если вы сами сохраняете файлы, используйте QSaveFile
как это касается промывки файла и аппроксимации замены атомарного файла, так что вы не потеряете настройки, если убийство (принудительное завершение) приходит в середине вас делать запись.
на aboutToQuit
сигнал, излучаемый QCoreApplication
это то, что вы хотите реагировать, если вы хотите просто сделать что-то когда приложения просят уйти. Это эквивалентно обработке WM_QUIT
сообщении или иметь дело с нет никакого смысла в обращении SIGTERM
на Unix. Поэтому делать это специфичным для платформы способом бессмысленно, поскольку Qt уже делает это для вас.WM_CLOSE
так как это сообщение, которое получает только windows, и снова Qt уже обрабатывает его для вас.
вы также можете участвовать в процессе выхода / выключения, установив QAbstractNativeEventFilter
и обработке WM_ENDSESSION
и WM_QUERYENDSESSION
. Это имеет смысл только в том случае, если вы хотите заранее знать, что приложение будет закрыто. Если вы явно не хотите остановить выключение / выход из системы, вам не нужно беспокоиться об этом.
Я думаю, что было бы лучше справиться с от QApplication::commitDataRequest сигнал (или QGuiApplication::commitDataRequest в Qt5) вместо aboutToQuit. Просто подключите сигнал к вашей функции для сохранения настроек.
вот некоторые связанные обсуждения:http://qt-project.org/forums/viewthread/33329
выход из сеанса будет излучать aboutToQuit
case WM_ENDSESSION: {
sm_smActive = false;
sm_blockUserInput = false;
bool endsession = (bool) wParam;
// we receive the message for each toplevel window included internal hidden ones,
// but the aboutToQuit signal should be emitted only once.
QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
if (endsession && !qAppPriv->aboutToQuitEmitted) {
qAppPriv->aboutToQuitEmitted = true;
int index = QApplication::staticMetaObject.indexOfSignal("aboutToQuit()");
qApp->qt_metacall(QMetaObject::InvokeMetaMethod, index,0);
// since the process will be killed immediately quit() has no real effect
QApplication::quit();
}
RETURN(0);
}
Я не знаю Qt. Если вы можете позволить себе быть только Windows WM_QUERYENDSESSION
и WM_ENDSESSION
сообщения могут быть правильным решением.