我有一个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();
}
然而,这不起作用。 CTRL-C似乎被捕获(应用程序没有被杀死),但它也没有退出。我错过了什么?
答案 0 :(得分:19)
可能有一种方法可以使用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
关联的默认操作。
答案 1 :(得分:17)
由于未记录,因此不应使用QApplication::watchUnixSignal
。并且,通过阅读代码,使用glib事件调度程序(这是Linux上的默认设置)时,它将无法正常工作。
但是,通常你可以安全地在Qt应用程序中捕获Unix信号,你只需要自己编写一些代码。文档中甚至还有一个示例 - Calling Qt Functions From Unix Signal Handlers。
答案 2 :(得分:1)
除了Qt 4.0的one liner之外,我没有找到更多关于QApplication::watchUnixSignal
文档的内容。尤其是在Qt的更高版本中没有记录。因此,看起来这个功能没有被广告(因此假设)工作。虽然这样做“Qt方式”显然很好,但我只是回过头来使用signal system call。
答案 3 :(得分:1)
正如Jerkface Jones所提到的,这似乎无法在Linux上使用默认事件处理程序。
如果Qt正在使用原始的Unix(非glib)事件处理程序,Qt会在其信号处理程序中立即捕获并吸收^ C,但在Qt执行事件处理之前不会发出unixSignal(int)信号
如果你有代码在运行(而不是等待Qt发送信号),那么你需要调用QApplication::processEvents()让Qt发送信号。
答案 4 :(得分:0)
您可以使用QApplication::instance()
(或较短的宏版本qApp
),它们至少在Qt4以后才可用:
#include <QApplication>
#include <csignal>
void sigHandler(int s)
{
std::signal(s, SIG_DFL);
qApp->quit();
}
int main(int argc, char * argv[])
{
QApplication app(argc, argv);
std::signal(SIGINT, sigHandler);
std::signal(SIGTERM, sigHandler);
return app.exec();
}