QApplication:如何在Ctrl-C上正常closures

我有一个QApplication,根据命令行参数,有时实际上没有一个GUI窗口,但只运行没有GUI。 在这种情况下,如果CTRL-C被击中,我想优雅地closures它。 基本上我的代码如下所示:

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

但是,这不起作用。 CTRL-C似乎被捕获(应用程序不会被杀死),但它也不会退出。 我错过了什么?

由于它没有记录, QApplication::watchUnixSignal不应该被使用。 而且,通过阅读代码,使用glib事件分派器(这是Linux上的默认设置)将无法正常工作。

但是,一般来说,您可以安全地在Qt应用程序中捕获Unix信号,您只需自己编写一些代码即可。 在文档中甚至有一个例子 – 从Unix信号处理程序调用Qt函数 。

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_()) 

这工作,并会关闭应用程序时,我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(); } 

不幸的是,我不能编译这个,所以可能需要一些修正,但是这应该给你一个总的想法。 通过使用SIG_DFL处理程序,您正在指示您的程序使用与Ctrl-C关联的默认操作。

除了Qt 4.0的QApplication::watchUnixSignal外,我还没有找到更多关于QApplication::watchUnixSignal文档。 特别是在Qt的更高版本中没有记录。 因此,看起来这个功能没有广告(因此应该)工作。 虽然这样做“Qt的方式”显然是不错的,我只是回到使用信号系统调用 。

正如Jerkface Jones提到的,这看起来像在Linux上使用默认事件处理程序不起作用。

如果Qt使用原始的unix(non-glib)事件处理程序,Qt将在其信号处理程序中立即捕获和吸收^ C,但是直到Qt进行事件处理之前,unixSignal(int)信号才会被发射。

如果你有代码运行(而不是等待Qt发送信号),那么你需要为Qt调用QApplication :: processEvents()来发送信号。