How to detect Windows shutdown or logoff in Qt

人盡茶涼 提交于 2019-12-12 08:49:39

问题


I am porting a Linux app to Windows written in Qt. The application needs to save some settings before closing. On Linux, we can do that by signal handlers for SIGTERM etc. How can I implement the same on Windows.


回答1:


If you are using the Qt event loop, you can catch the following signal:

void QCoreApplication::aboutToQuit() [signal]

This signal is emitted when the application is about to quit the main event loop, e.g. when the event loop level drops to zero. This may happen either after a call to quit() from inside the application or when the users shuts down the entire desktop session. The signal is particularly useful if your application has to do some last-second cleanup. Note that no user interaction is possible in this state.

Other than that, you may be looking for the following messages below if the aforementioned signal is not appropriate for your use case:

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




回答2:


I think the other answers completely miss the point: When you forcibly end an application, it's like SIGKILL on Unix. There's no way to handle it - except ahead of time. What I mean by handling it ahead of time is making sure that you save the settings every time they are changed. Of course you can optimize this behavior, for example save the settings every few seconds if they are dirty, if you want to minimize the number of disk accesses (think power consumption on mobile devices).

A lot of this is handled by QSettings for you. As long as you use QSettings, you'll get reasonable behavior. If you're saving files yourself, use QSaveFile as it deals with flushing the file and approximating atomic file replacement, so that you won't lose the settings if the kill (forced termination) comes in the middle of you doing the writing.

The aboutToQuit signal emitted by QCoreApplication is what you want to react to if you want to simply do something when the application being asked to quit. This is equivalent to handling the WM_QUIT message, or dealing with SIGTERM on Unix. So doing it in platform-specific way is pointless as Qt does it for you already. There's equally no point in handling WM_CLOSE since that's a message that only windows get, and again Qt already handles it for you.

You can also participate in the logoff/shutdown process by installing a QAbstractNativeEventFilter and processing the WM_ENDSESSION and WM_QUERYENDSESSION. This only makes sense if you want to know ahead of time that the application will be quit. Unless you explicitly want to stop the shutdown/logoff, you don't need to worry about it.




回答3:


session logoff will emit 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);
}



回答4:


I think it might be better to handle the QApplication::commitDataRequest signal (or QGuiApplication::commitDataRequest in Qt5) instead of aboutToQuit. Just connect the signal to your function for saving settings.

Here are some related discussions: http://qt-project.org/forums/viewthread/33329




回答5:


I do not know Qt. If you can afford to be Windows only WM_QUERYENDSESSION and WM_ENDSESSION messages might be the right thing to do.



来源:https://stackoverflow.com/questions/19195935/how-to-detect-windows-shutdown-or-logoff-in-qt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!