QApplication:如何在 Ctrl-C 上正常关闭
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2300401/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
QApplication: How to shutdown gracefully on Ctrl-C
提问by Martin
I have a QApplication
that, depending on command line parameters, sometimes doesn't actually have a GUI window, but just runs without GUI. In this case, I want to shut it down gracefully if CTRL-Cwas hit. Basically my code looks like this:
我有一个QApplication
,取决于命令行参数,有时实际上没有 GUI 窗口,但只是在没有 GUI 的情况下运行。在这种情况下,如果CTRL-C被击中,我想优雅地关闭它。基本上我的代码是这样的:
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
... // parse command line options
if (no_gui) {
QObject::connect(&app, SIGNAL(unixSignal(int)),
&app, SLOT(quit()));
app.watchUnixSignal(SIGINT, true);
app.watchUnixSignal(SIGTERM, true);
}
...
return app.exec();
}
However, this does not work. CTRL-Cseems to be caught (the application doesn't get killed), but it also doesn't exit. What am I missing?
但是,这不起作用。CTRL-C似乎被抓住了(应用程序没有被杀死),但它也没有退出。我错过了什么?
采纳答案by rohanpm
As it isn't documented, QApplication::watchUnixSignal
shouldn't be used. And, from reading the code, it will not work properly when using the glib event dispatcher (which is the default on Linux).
因为它没有记录,所以QApplication::watchUnixSignal
不应该使用。而且,从阅读代码来看,在使用 glib 事件调度程序(这是 Linux 上的默认设置)时,它将无法正常工作。
However, in general you cansafely catch Unix signals in Qt applications, you just have to write a bit of the code yourself. There is even an example in the documentation - Calling Qt Functions From Unix Signal Handlers.
但是,通常您可以安全地在 Qt 应用程序中捕获 Unix 信号,您只需要自己编写一些代码即可。文档中甚至还有一个示例 - Calling Qt Functions From Unix Signal Handlers。
回答by swanson
There may be a way to do this natively with Qt -- I poked around the QKeySequence docs for a bit before giving up, but you can just use signal
. I don't have Qt/C++ setup on my machine at the moment, but I do have the Python bindings.
可能有一种方法可以使用 Qt 本地完成此操作——我在放弃之前浏览了 QKeySequence 文档,但您可以只使用signal
. 目前我的机器上没有 Qt/C++ 设置,但我有 Python 绑定。
import sys, signal
from PyQt4 import QtGui
app = QtGui.QApplication(sys.argv)
signal.signal(signal.SIGINT, signal.SIG_DFL)
sys.exit(app.exec_())
This works and will close the application when I do Ctrl-C. So I believe that your application could adapt this code and it would end up something like this:
这有效并且将在我执行Ctrl-时关闭应用程序C。所以我相信你的应用程序可以调整这段代码,它最终会是这样的:
#include <signal.h>
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
... // parse command line options
if (no_gui) {
signal(SIGINT, SIG_DFL);
}
...
return app.exec();
}
Unfortunately, I cannot compile this so it will probably need a few fixes, but this should give you the general idea. By using the SIG_DFL
handler you are instructing your program to use the default action associated with Ctrl-C.
不幸的是,我无法编译它,所以它可能需要一些修复,但这应该给你一个大致的想法。通过使用SIG_DFL
处理程序,您将指示您的程序使用与Ctrl-关联的默认操作C。
回答by andrewffff
As Jerkface Jones mentioned, this looks like it doesn't work using the default event handler on Linux.
正如 Jerkface Jones 所提到的,这看起来在 Linux 上使用默认事件处理程序不起作用。
If Qt is using the raw Unix (non-glib) event handler, Qt will catch and absorb the ^C right away in its signal handler, but the unixSignal(int) signal won't be emitted until Qt does event processing.
如果 Qt 使用原始 Unix(非 glib)事件处理程序,Qt 将立即在其信号处理程序中捕获并吸收 ^C,但在 Qt 进行事件处理之前不会发出 unixSignal(int) 信号。
If you have code running (rather than idling around waiting for Qt to send signals), then you'll need to call QApplication::processEvents()for Qt to send the signal.
如果您有代码正在运行(而不是闲着等待 Qt 发送信号),那么您需要调用QApplication::processEvents()让 Qt 发送信号。
回答by bluebrother
I haven't found much more about QApplication::watchUnixSignal
documentation except for a one linerfor Qt 4.0; especially it's not documented in later versions of Qt. Thus it looks like this functionality isn't advertised (and therefore supposed) to work. While doing it the "Qt way" is obviously nice I'd simply fall back to using the signal system callinstead.
QApplication::watchUnixSignal
除了Qt 4.0的一个衬垫之外,我没有找到更多关于文档的信息;尤其是在 Qt 的更高版本中没有记录。因此,看起来这个功能没有被宣传(因此应该)工作。在这样做时,“Qt 方式”显然很好,我只是回退到使用信号系统调用。