QApplication:如何在Ctrl-C上正常关闭

Mar*_*tin 24 c++ unix qt

我有一个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();
}
Run Code Online (Sandbox Code Playgroud)

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

swa*_*son 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_())
Run Code Online (Sandbox Code Playgroud)

当我这样做时,这将起作用并关闭应用程序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();
}
Run Code Online (Sandbox Code Playgroud)

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


roh*_*npm 18

由于没有记录,QApplication::watchUnixSignal不应使用.并且,通过阅读代码,使用glib事件调度程序(这是Linux上的默认设置)时它将无法正常工作.

但是,通常你可以安全地在Qt应用程序中捕获Unix信号,你只需要自己编写一些代码.文档中甚至还有一个例子 - 从Unix信号处理程序调用Qt函数.


Chn*_*sos 8

您可以使用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();
}
Run Code Online (Sandbox Code Playgroud)