2010-02-19 20 views
20

Tengo una QApplication que, dependiendo de los parámetros de línea de comandos, a veces no tiene una ventana GUI, pero simplemente se ejecuta sin GUI. En este caso, quiero cerrarlo con gracia si se presionó CTRL-C. Básicamente mi código se ve así:QApplication: Cómo cerrar con gracia en 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(); 
} 

Sin embargo, esto no funciona. CTRL-C parece estar atrapado (la aplicación no muere), pero tampoco sale. ¿Qué me estoy perdiendo?

+0

[Esto está muy bien documentado. Use la documentación.] (Http://doc.qt.io/qt-5/unix-signals.html) –

Respuesta

15

Como no está documentado, QApplication::watchUnixSignal no debe utilizarse. Y, al leer el código, no funcionará correctamente cuando se use el despachador de eventos glib (que es el predeterminado en Linux).

Sin embargo, en general, puede capturar de manera segura las señales de Unix en aplicaciones de Qt, solo tiene que escribir un poco del código usted mismo. Incluso hay un ejemplo en la documentación: Calling Qt Functions From Unix Signal Handlers.

+0

Como no hay forma de comentar sobre esa página, solo haré una pregunta rápida aquí, con la esperanza que será útil para otros: ¿Por qué parte de la inicialización se separó en su propio método estático "static int setup_unix_signal_handlers()"? –

+0

No veo ningún motivo para que setup_unix_signal_handlers() sea estático, y funciona bien como parte de un método de instancia. Las matrices de descriptores de archivos también pueden ser no estáticas, pero solo si tiene C++ 11 o una sintaxis de inicialización mayor. – rholmes

1

No he encontrado mucho más sobre la documentación QApplication::watchUnixSignal a excepción de un one liner para Qt 4.0; especialmente no está documentado en versiones posteriores de Qt. Por lo tanto, parece que esta funcionalidad no se anuncia (y, por lo tanto, se supone) para funcionar. Mientras lo hago, la "forma de Qt" es obviamente buena, simplemente me limitaría a usar el signal system call.

17

Puede haber una forma de hacer esto de forma nativa con Qt - He hurgado un poco en los documentos de QKeySequence antes de darme por vencido, pero solo puede usar signal. No tengo la configuración de Qt/C++ en mi máquina en este momento, pero sí tengo los enlaces de Python.

import sys, signal 
from PyQt4 import QtGui 

app = QtGui.QApplication(sys.argv) 
signal.signal(signal.SIGINT, signal.SIG_DFL) 

sys.exit(app.exec_()) 

Esto funciona y se cerrará la aplicación cuando lo haga Ctrl-C. Así que creo que su aplicación podría adaptar este código y que terminaría así:

#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(); 
} 

Por desgracia, no puedo compilar este modo es probable que necesita algunos arreglos, pero esto debe darle la idea general. Al utilizar el controlador SIG_DFL, está indicando a su programa que use la acción predeterminada asociada con Ctrl-C.

1

Como mencionó Jerkface Jones, parece que no funciona con el controlador de eventos predeterminado en Linux.

Si Qt usa el controlador de eventos raw Unix (no glib), Qt capturará y absorberá el^C de inmediato en su controlador de señal, pero la señal de unixSignal (int) no se emitirá hasta que Qt lo haga tratamiento.

Si tiene un código en ejecución (en lugar de estar inactivo esperando que Qt envíe señales), entonces deberá llamar al QApplication::processEvents() para que Qt envíe la señal.

+1

Jerkface Jones? –

Cuestiones relacionadas