问题
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.
回答1:
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
回答2:
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 There's equally no point in handling SIGTERM
on Unix. So doing it in platform-specific way is pointless as Qt does it for you already.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.
回答3:
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);
}
回答4:
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
回答5:
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.
来源:https://stackoverflow.com/questions/19195935/how-to-detect-windows-shutdown-or-logoff-in-qt