我正在将一个Linux应用程序移植到用Qt编写的Windows。应用程序需要在关闭前保存一些设置。在Linux上,我们可以通过SIGTERM等的信号处理程序来实现。我如何在Windows上实现相同的功能。
答案 0 :(得分:7)
如果您正在使用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/en-US/library/windows/desktop/aa376890.aspx
WM_ENDSESSION:http://msdn.microsoft.com/en-US/library/windows/desktop/aa376889.aspx
答案 1 :(得分:2)
我认为其他答案完全错过了重点:当你强行结束一个应用程序时,它就像Unix上的SIGKILL。 没有办法处理它 - 除了提前。我提前处理它的意思是确保每次更改时都保存设置。当然,您可以优化此行为,例如,如果您想要最小化磁盘访问次数(考虑移动设备上的功耗),则每隔几秒钟保存设置(如果它们是脏的)。
很多问题由QSettings
处理。只要您使用QSettings
,您就会获得合理的行为。如果你自己保存文件,请使用QSaveFile
,因为它处理刷新文件和近似原子文件替换,这样如果kill(强制终止)出现在你做的中间你就不会丢失设置写作。
如果您想要在要求退出应用程序时执行某些操作,aboutToQuit
发出的QCoreApplication
信号就是您想要做出的反应。这相当于在Unix上处理WM_QUIT
消息,或处理处理{{1}}同样毫无意义,因为这是一条只有Windows获取的消息,而且Qt已经为您处理了它SIGTERM
。因此,以特定于平台的方式执行此操作毫无意义,因为Qt已经为您完成了。
您还可以通过安装WM_CLOSE
并处理QAbstractNativeEventFilter
和WM_ENDSESSION
来参与注销/关闭流程。如果您想提前知道应用程序将退出,这才有意义。除非您明确要停止关闭/注销,否则无需担心。
答案 2 :(得分:1)
我认为处理QApplication::commitDataRequest信号(或Qt5中的QGuiApplication::commitDataRequest)而不是aboutToQuit可能会更好。只需将信号连接到您的功能即可保存设置。
答案 3 :(得分:1)
会话注销将发出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 :(得分:0)
我不知道Qt。如果您能够只使用Windows WM_QUERYENDSESSION
和WM_ENDSESSION
消息可能是正确的做法。