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

时间:2013-10-05 09:02:49

标签: c++ windows qt qt-signals qtcore

我正在将一个Linux应用程序移植到用Qt编写的Windows。应用程序需要在关闭前保存一些设置。在Linux上,我们可以通过SIGTERM等的信号处理程序来实现。我如何在Windows上实现相同的功能。

5 个答案:

答案 0 :(得分:7)

如果您正在使用Qt事件循环,则可以捕获以下信号:

  

void QCoreApplication :: aboutToQuit()[signal]

     

当应用程序即将退出主事件循环时发出此信号,例如,当事件循环级别降至零时。这可能在从应用程序内部调用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

答案 1 :(得分:2)

我认为其他答案完全错过了重点:当你强行结束一个应用程序时,它就像Unix上的SIGKILL。 没有办法处理它 - 除了提前我提前处理它的意思是确保每次更改时都保存设置。当然,您可以优化此行为,例如,如果您想要最小化磁盘访问次数(考虑移动设备上的功耗),则每隔几秒钟保存设置(如果它们是脏的)。

很多问题由QSettings处理。只要您使用QSettings,您就会获得合理的行为。如果你自己保存文件,请使用QSaveFile,因为它处理刷新文件和近似原子文件替换,这样如果kill(强制终止)出现在你做的中间你就不会丢失设置写作。

如果您想要在要求退出应用程序时执行某些操作,aboutToQuit发出的QCoreApplication信号就是您想要做出的反应。这相当于在Unix上处理WM_QUIT消息,或处理SIGTERM。因此,以特定于平台的方式执行此操作毫无意义,因为Qt已经为您完成了。处理{​​{1}}同样毫无意义,因为这是一条只有Windows获取的消息,而且Qt已经为您处理了它

您还可以通过安装WM_CLOSE并处理QAbstractNativeEventFilterWM_ENDSESSION来参与注销/关闭流程。如果您想提前知道应用程序将退出,这才有意义。除非您明确要停止关闭/注销,否则无需担心。

答案 2 :(得分:1)

我认为处理QApplication::commitDataRequest信号(或Qt5中的QGuiApplication::commitDataRequest)而不是aboutToQuit可能会更好。只需将信号连接到您的功能即可保存设置。

以下是一些相关讨论:http://qt-project.org/forums/viewthread/33329

答案 3 :(得分:1)

会话注销将发出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 :(得分:0)

我不知道Qt。如果您能够只使用Windows WM_QUERYENDSESSIONWM_ENDSESSION消息可能是正确的做法。