c++ Q应用:如何在Ctrl-C上正常关机

q8l4jmvw  于 2023-03-05  发布在  其他
关注(0)|答案(5)|浏览(167)

我有一个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似乎被捕获(应用程序没有被杀死),但它也没有退出。我错过了什么?

vulvrdjw

vulvrdjw1#

也许有一种方法可以在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相关联的默认操作。

a9wyjsp7

a9wyjsp72#

由于没有文档说明,所以不应该使用QApplication::watchUnixSignal,而且,从阅读代码来看,当使用glib事件调度器(Linux上的默认值)时,它将无法正常工作。
不过,一般来说,你可以在Qt应用程序中安全地捕获Unix信号,你只需要自己写一点代码,文档中甚至有一个例子-Calling Qt Functions From Unix Signal Handlers

ktca8awb

ktca8awb3#

您可以使用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();
}
guykilcj

guykilcj4#

除了Qt 4.0的一个行程序外,我没有找到更多关于QApplication::watchUnixSignal的文档;特别是在Qt的后续版本中没有记录。因此,看起来这个功能没有被宣传(因此也不应该)工作。虽然“Qt方式”显然很好,但我只是回到使用signal system call来代替。

iyfamqjs

iyfamqjs5#

正如Jerkface Jones所提到的,在Linux上使用默认事件处理程序似乎不起作用。
如果Qt使用的是原始的Unix(non-glib)事件处理程序,Qt会立即在其信号处理程序中捕获并吸收^C,但unixSignal(int)信号只有在Qt完成事件处理后才会发出。
如果您正在运行代码(而不是无所事事地等待Qt发送信号),那么您需要调用QApplication::processEvents()让Qt发送信号。

相关问题