Вопрос

I am porting a Linux app to Windows written in Qt. 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.

Это было полезно?

Решение

If you are using the Qt event loop, you can catch the following signal:

void QCoreApplication::aboutToQuit() [signal]

This signal is emitted when the application is about to quit the main event loop, e.g. 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. 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_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

Другие советы

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.

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. This is equivalent to handling the WM_QUIT message, or dealing with SIGTERM on Unix. So doing it in platform-specific way is pointless as Qt does it for you already. 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.

You can also participate in the logoff/shutdown process by installing a QAbstractNativeEventFilter and processing the WM_ENDSESSION and WM_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. Just connect the signal to your function for saving settings.

Here are some related discussions: http://qt-project.org/forums/viewthread/33329

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

I do not know Qt. If you can afford to be Windows only WM_QUERYENDSESSION and WM_ENDSESSION messages might be the right thing to do.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top