6

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

4

5 回答 5

10

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

void QCoreApplication::aboutToQuit() [信号]

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

于 2013-10-05T09:11:05.923 回答
5

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.

如果您想在应用程序被要求退出时简单地做某事,则aboutToQuit发出的信号就是您想要做出反应的信号。QCoreApplication这相当于处理WM_QUIT消息,或者SIGTERM在 Unix 上处理。因此,以特定于平台的方式进行操作是没有意义的,因为 Qt 已经为您完成了。处理同样没有意义,WM_CLOSE因为这是只有 Windows 才能获得的消息,而且 Qt 已经为您处理了。

QAbstractNativeEventFilter您还可以通过安装 a并处理WM_ENDSESSIONand来参与注销/关闭过程WM_QUERYENDSESSION。仅当您想提前知道应用程序将被退出时,这才有意义。除非您明确想要停止关机/注销,否则您无需担心。

于 2013-10-13T20:48:28.403 回答
2

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

于 2013-10-14T20:45:43.540 回答
2

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);
}
于 2018-04-14T05:54:23.840 回答
1

我不知道Qt。如果您负担得起仅使用 Windows的费用WM_QUERYENDSESSION,那么WM_ENDSESSION消息可能是正确的做法。

于 2013-10-05T10:26:01.573 回答