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

C++ 如何在Qt中检测Windows关闭或注销,c++,windows,qt,qt-signals,qtcore,C++,Windows,Qt,Qt Signals,Qtcore,我正在将Linux应用程序移植到用Qt编写的Windows。应用程序需要在关闭前保存一些设置。在Linux上,我们可以通过SIGTERM等的信号处理程序来实现。如何在Windows上实现相同的功能。如果使用Qt事件循环,可以捕获以下信号: void QCoreApplication::aboutToQuit()[信号] 该信号在应用程序即将退出主事件循环时发出,例如,当事件循环级别降至零时。这可能发生在从应用程序内部调用quit()之后,也可能发生在用户关闭整个桌面会话时。 如果应用程序必须在最

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

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

void QCoreApplication::aboutToQuit()[信号]

该信号在应用程序即将退出主事件循环时发出,例如,当事件循环级别降至零时。这可能发生在从应用程序内部调用quit()之后,也可能发生在用户关闭整个桌面会话时。 如果应用程序必须在最后一秒进行清理,则该信号特别有用。请注意,在此状态下不可能进行用户交互

除此之外,如果上述信号不适合您的用例,您可能会在下面查找以下消息:

WM_退出:

WM_关闭:

WM_查询结束会话:


WM_ENDSESSION:

我不知道Qt。如果你可以只使用Windows,那么消息可能是正确的选择。

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

很多问题都是由
QSettings
为您处理的。只要你使用
QSettings
,你就会得到合理的行为。如果您自己保存文件,请使用<代码> QSaveFiel处理文件和近似原子文件替换,这样,如果在写入过程中发生了“终止(强制终止)”,则不会丢失设置。
QCoreApplication
发出的
aboutToQuit
信号是当应用程序被要求退出时,如果您想简单地执行某项操作,您希望做出的反应。这相当于在Unix上处理
WM_QUIT
消息,或处理
SIGTERM
。所以,以特定于平台的方式进行操作是毫无意义的,因为Qt已经为您完成了。处理
WM_CLOSE
同样没有意义,因为这是一条只有windows才能收到的消息,而Qt已经为您处理了


您还可以通过安装
QAbstractNativeEventFilter
并处理
WM\u ENDSESSION
WM\u QUERYENDSESSION
来参与注销/关闭过程。只有当您想提前知道应用程序将退出时,这才有意义。除非您明确希望停止关机/注销,否则您不必担心。

我认为处理信号(或在Qt5中)可能比处理退出更好。只需将信号连接到保存设置的功能


下面是一些相关的讨论:

会话注销将发出关于退出的

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);
}

我不知道Linux上的ToQuit处理sigterm,但是sighup和sigint呢?在Linux中,sighup通常在注销时发送到应用程序,这就是为什么我在Linux上使用信号处理程序(Qt-way平台特定)的原因。关于这个问题,没有任何东西说应用程序被强制终止。它提到了
SIGTERM
,这是一个优雅的关机信号,而不是
SIGKILL