У меня есть 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, кажется, пойман (приложение не становится уничтоженным), но это также не выходит. Что я пропускаю?
Поскольку она не документирована, QApplication::watchUnixSignal
не следует использовать. И, судя по коду, она не будет работать правильно при использовании диспетчера событий glib (который используется по умолчанию в Linux).
Однако, в целом, вы можете безопасно ловить сигналы Unix в приложениях Qt, вам просто придется написать немного кода самостоятельно. В документации даже есть пример - Вызов функций Qt из обработчиков сигналов Unix.
Как упоминал Джеркфейс Джонс, похоже, что это не работает с использованием обработчика событий по умолчанию в Linux.
Если Qt использует необработанный обработчик событий Unix (не glib), Qt сразу поймает и поглотит ^ C в своем обработчике сигнала, но сигнал unixSignal (int) не будет испускаться, пока Qt не выполнит обработку события .
Если у вас работает код (вместо того, чтобы бездельничать в ожидании отправки сигналов Qt), вам нужно вызвать QApplication :: processEvents () , чтобы Qt отправила сигнал.
Я не нашел более подробной информации о QApplication :: watchUnixSignal
документации, за исключением однострочника для Qt 4.0; особенно это не задокументировано в более поздних версиях Qt. Таким образом, похоже, что эта функция не рекламируется (и, следовательно, не предполагается) для работы. Хотя использование «способа Qt», очевидно, неплохо, я бы просто вернулся к использованию системного вызова signal .
Может быть способ сделать это изначально с 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
.