QApplication: как закончить изложение на Ctrl-C
У меня есть QApplication, который, в зависимости от параметров командной строки, иногда на самом деле не имеет окна графического интерфейса, а просто работает без 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 кажется пойманным (приложение не убивается), но оно также не выходит. Что мне не хватает?
Ответы
Ответ 1
Как не документировано, QApplication::watchUnixSignal
не следует использовать. И, читая код, он не будет работать должным образом при использовании диспетчера событий glib (который по умолчанию используется в Linux).
Однако, в общем, вы можете безопасно поймать сигналы Unix в приложениях Qt, вам просто нужно написать немного кода самостоятельно. В документации есть даже пример: Вызов функций Qt из обработчиков сигналов Unix.
Ответ 2
Возможно, есть способ сделать это изначально с помощью Qt - я немного поиграл с документами QKeySequence, прежде чем сдаваться, но вы можете просто использовать signal
. На данный момент у меня нет настройки Qt/С++ на моей машине, но у меня есть привязки 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
.
Ответ 3
Я не нашел больше о документации QApplication::watchUnixSignal
, кроме один лайнер для Qt 4.0; особенно это не задокументировано в более поздних версиях Qt. Таким образом, похоже, что эта функция не рекламируется (и поэтому должна) работать. Несмотря на то, что "Qt way" явно приятен, я просто вернусь к использованию сигнального системного вызова.
Ответ 4
Как упоминал Jerkface Jones, похоже, что он не работает с использованием обработчика событий по умолчанию в Linux.
Если Qt использует необработанный обработчик событий Unix (без glib), Qt сразу поймает и поглотит ^ C в своем обработчике сигнала, но сигнал unixSignal (int) не будет выпущен до тех пор, пока Qt не обработает события.
Если у вас работает код (а не на холостом ходу, ожидая отправки Qt для отправки сигналов), вам нужно будет вызвать QApplication:: processEvents() для Qt для отправки сигнала.