簡體   English   中英

QApplication:如何在 Ctrl-C 上正常關閉

[英]QApplication: How to shutdown gracefully on Ctrl-C

我有一個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似乎被捕獲(應用程序沒有被殺死),但它也沒有退出。 我錯過了什么?

可能有一種方法可以使用 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關聯的默認操作。

由於沒有記錄,不應使用QApplication::watchUnixSignal 而且,從閱讀代碼來看,在使用 glib 事件調度程序(這是 Linux 上的默認設置)時,它將無法正常工作。

但是,通常您可以安全地在 Qt 應用程序中捕獲 Unix 信號,您只需要自己編寫一些代碼即可。 文檔中甚至還有一個示例 - Calling Qt Functions From Unix Signal Handlers

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

我還沒有更多關於發現QApplication::watchUnixSignal除了一個文件 一個襯墊Qt的4.0; 尤其是在 Qt 的更高版本中沒有記錄。 因此看起來這個功能沒有被宣傳(因此應該)工作。 在這樣做時,“Qt 方式”顯然很好,我只是回退到使用信號系統調用

正如 Jerkface Jones 所提到的,這看起來在 Linux 上使用默認事件處理程序不起作用。

如果 Qt 使用原始 Unix(非 glib)事件處理程序,Qt 將立即在其信號處理程序中捕獲並吸收 ^C,但在 Qt 進行事件處理之前不會發出 unixSignal(int) 信號。

如果您有代碼正在運行(而不是閑着等待 Qt 發送信號),那么您需要調用QApplication::processEvents()讓 Qt 發送信號。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM