2016-01-17 3 views
1

Я пытаюсь создать главный цикл событий PySide, поддерживаемый gevent, на основе someone else's code. Следующий код использует оригинальный .exec_() метод и работает правильно:Как запускать сигнал aboutToQuit вручную в PySide

... 

if __name__ == "__main__": 
    app = QtGui.QApplication(sys.argv) 
    win = MyGuiClass() 
    win.ui.show() 

    def on_exit(): 
     print "bye..." 

    app.aboutToQuit.connect(on_exit) 
    app.exec_() 

При нажатии на кнопку X в главном окне, on_exit() функция вызывается и bye... строка выводится на консоль, а также.

Для поддержки GEvent, мне нужно, чтобы вставить gevent.sleep(0.01) где-то внутри app.exec_() петли, поэтому я определил следующую функцию:

def wait_app(app): 
    app_is_running = True 
    while app_is_running: 
     app.processEvents() 
     gevent.sleep(0.01) 

, а затем изменили исходный код следующим образом:

... 

if __name__ == "__main__": 
    app = QtGui.QApplication(sys.argv) 
    win = MyGuiClass() 
    win.ui.show() 

    def on_exit(): 
     print "bye..." 

    app.aboutToQuit.connect(on_exit) 
    wait_app(app) 

Затем приложение Gui работает отлично, как и раньше, и зеленые деревья, созданные Gevent, работают параллельно, как и ожидалось.

Проблема только в том, что когда я нажимаю кнопку X в главном окне, приложение Qt завершается (окно закрывается), но функция on_exit() не вызывается, поэтому оставшиеся зеленые панели остаются рабочими. Как я могу вручную определить, произошло ли нажатие кнопки главного окна X нажатием кнопки QtGui.QApplication() (app)?

Редактировать

Учитывая предложение в принятом ответе, рабочая реализация выглядит следующим образом:

if __name__ == "__main__": 
    app = QtGui.QApplication(sys.argv) 

    timer = QtCore.QTimer() 
    import gevent 
    def gevent_loop(): 
     gevent.sleep(0.01) 
     timer.start(0) 
    timer.timeout.connect(gevent_loop) 
    timer.start(0) 

    win = test() 
    win.ui.show() 
    app.exec_() 

Edit 2

Ниже приведен пример применения: https://github.com/ceremcem/weighing-machine-testing

ответ

2

QCoreApplication::exec() сам метод отвечает за излучение сигнала aboutToQuit (по крайней мере, с Qt 4.x). Поскольку вы обходите exec() с помощью собственного простого цикла событий, этот сигнал никогда не выделяется.

Вместо повторной реализации exec(), то QCoreApplicationdocumentation рекомендует другой подход:

Чтобы сделать ваше приложение выполняет ожидания обработки (т.е. выполняет специальную функцию, когда нет ожидающих событий), используйте QTimer с 0 тайм-аут.

Я ничего не знаю о Gevent, но вы можете попробовать использовать таймер, чтобы вызвать вызов gevent.sleep(0.01) через каждый проход через цикл событий. Таким образом, вы можете быть уверены, что не обходитесь ни одному встроенному поведению, реализованному exec().