QApplication: Как завершить работу корректно на 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, кажется, пойман (приложение не становится уничтоженным), но это также не выходит. Что я пропускаю?

24
задан Martin 19 February 2010 в 23:49
поделиться

4 ответа

Поскольку она не документирована, QApplication::watchUnixSignal не следует использовать. И, судя по коду, она не будет работать правильно при использовании диспетчера событий glib (который используется по умолчанию в Linux).

Однако, в целом, вы можете безопасно ловить сигналы Unix в приложениях Qt, вам просто придется написать немного кода самостоятельно. В документации даже есть пример - Вызов функций Qt из обработчиков сигналов Unix.

18
ответ дан 28 November 2019 в 23:42
поделиться

Как упоминал Джеркфейс Джонс, похоже, что это не работает с использованием обработчика событий по умолчанию в Linux.

Если Qt использует необработанный обработчик событий Unix (не glib), Qt сразу поймает и поглотит ^ C в своем обработчике сигнала, но сигнал unixSignal (int) не будет испускаться, пока Qt не выполнит обработку события .

Если у вас работает код (вместо того, чтобы бездельничать в ожидании отправки сигналов Qt), вам нужно вызвать QApplication :: processEvents () , чтобы Qt отправила сигнал.

1
ответ дан 28 November 2019 в 23:42
поделиться

Я не нашел более подробной информации о QApplication :: watchUnixSignal документации, за исключением однострочника для Qt 4.0; особенно это не задокументировано в более поздних версиях Qt. Таким образом, похоже, что эта функция не рекламируется (и, следовательно, не предполагается) для работы. Хотя использование «способа Qt», очевидно, неплохо, я бы просто вернулся к использованию системного вызова signal .

1
ответ дан 28 November 2019 в 23:42
поделиться

Может быть способ сделать это изначально с 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 .

19
ответ дан 28 November 2019 в 23:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: