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

8

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

5个回答

10
如果您正在使用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/zh-cn/library/windows/desktop/aa376890.aspx

WM_ENDSESSION:http://msdn.microsoft.com/zh-cn/library/windows/desktop/aa376889.aspx


6
我认为其他回答完全错了重点:当你强制结束一个应用程序时,就像在Unix上的SIGKILL。没有办法处理它 - 除非提前处理好。提前处理的意思是确保每次更改设置时都保存设置。当然,您可以优化此行为,例如如果它们是脏的,每隔几秒钟保存一次设置,以最小化磁盘访问次数(考虑移动设备上的功耗)。
很多这些都由QSettings为您处理。只要使用QSettings,您将获得合理的行为。如果您自己保存文件,请使用QSaveFile,因为它处理刷新文件和近似原子文件替换,以便在您进行写入时在kill(强制终止)中间不会丢失设置。
如果您只想在应用程序被要求退出时执行某些操作,则要反应的是由QCoreApplication发出的aboutToQuit信号。这相当于处理WM_QUIT消息,或在Unix上处理SIGTERM。因此,以平台特定的方式处理它是毫无意义的,因为Qt已经为您处理了。同样,处理WM_CLOSE也没有意义,因为那是只有窗口才能收到的消息,而Qt已经为您处理了。
您还可以通过安装QAbstractNativeEventFilter并处理WM_ENDSESSION和WM_QUERYENDSESSION来参与注销/关闭过程。除非您明确想要停止关闭/注销,否则您不需要担心它。

我不知道关于在Linux上如何处理sigterm的toQuit,但是sighup和sigint呢?sighup通常在Linux注销时发送给应用程序,这就是为什么我在Linux上使用了信号处理程序(Qt平台特定)。 - adnan kamili
问题中并没有提到应用程序被强制结束。它提到了“SIGTERM”,这是一种优雅的关闭信号,而不是“SIGKILL”。 - qris

3

2

会话注销将发出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);
}

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接