简体   繁体   English

如何在Qt中检测Windows关闭或注销

[英]How to detect Windows shutdown or logoff in Qt

I am porting a Linux app to Windows written in Qt. 我正在将一个Linux应用程序移植到用Qt编写的Windows。 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. 在Linux上,我们可以通过SIGTERM等的信号处理程序来实现。我如何在Windows上实现相同的功能。

If you are using the Qt event loop, you can catch the following signal: 如果您使用的是Qt事件循环,则可以捕获以下信号:

void QCoreApplication::aboutToQuit() [signal] void QCoreApplication :: aboutToQuit()[signal]

This signal is emitted when the application is about to quit the main event loop, eg 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. 这可能在从应用程序内部调用quit()之后或用户关闭整个桌面会话时发生。 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_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_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_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 WM_ENDSESSION: http//msdn.microsoft.com/en-US/library/windows/desktop/aa376889.aspx

I think the other answers completely miss the point: When you forcibly end an application, it's like SIGKILL on Unix. 我认为其他答案完全忽略了这一点: 当你强行结束一个应用程序时,它就像Unix上的SIGKILL。 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. 很多这都是由QSettings为您处理的。 As long as you use QSettings , you'll get reasonable behavior. 只要你使用QSettings ,你就会得到合理的行为。 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. 如果您自己保存文件,请使用QSaveFile因为它处理刷新文件和近似原子文件替换,这样如果kill(强制终止)进入写入过程中,您将不会丢失设置。

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. QCoreApplication发出的aboutToQuit信号是你想要响应的,如果你想在要求退出应用程序时简单地做一些事情。 This is equivalent to handling the WM_QUIT message, or dealing with SIGTERM on Unix. 这相当于处理WM_QUIT消息, 或者在Unix上处理SIGTERM So doing it in platform-specific way is pointless as Qt does it for you already. 所以在平台特定的方式做这件事是没有意义的,因为Qt已经为你做了。 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. 处理WM_CLOSE同样毫无意义,因为这是一个只有Windows获取的消息,而且Qt已经为你处理了它。

You can also participate in the logoff/shutdown process by installing a QAbstractNativeEventFilter and processing the WM_ENDSESSION and WM_QUERYENDSESSION . 您还可以通过安装QAbstractNativeEventFilter并处理WM_ENDSESSIONWM_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. 除非您明确要停止关闭/注销,否则无需担心。

I think it might be better to handle the QApplication::commitDataRequest signal (or QGuiApplication::commitDataRequest in Qt5) instead of aboutToQuit. 我认为处理QApplication :: commitDataRequest信号(或Qt5中的QGuiApplication :: commitDataRequest)而不是aboutToQuit可能会更好。 Just connect the signal to your function for saving settings. 只需将信号连接到您的功能即可保存设置。

Here are some related discussions: http://qt-project.org/forums/viewthread/33329 以下是一些相关的讨论: http//qt-project.org/forums/viewthread/33329

session logoff will emit aboutToQuit 会话注销将发出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);
}

I do not know Qt. 我不知道Qt。 If you can afford to be Windows only WM_QUERYENDSESSION and WM_ENDSESSION messages might be the right thing to do. 如果你能负担得起Windows只有WM_QUERYENDSESSIONWM_ENDSESSION消息可能是正确的做法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM