如何在PySide中手动触发aboutToQuit信号

时间:2016-01-17 20:54:09

标签: qt pyside gevent

我试图基于someone else's code创建一个支持gevent的PySide主事件循环。以下代码使用原始.exec_()方法并正确运行:

...

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的greenlet按预期并行运行。

唯一的问题是,当我单击主窗口上的X按钮时,Qt应用程序终止(窗口关闭)但on_exit()函数未被调用,因此剩余的greenlet仍然有效。如何通过XQtGui.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_()

编辑2

以下是一个示例应用程序:https://github.com/ceremcem/weighing-machine-testing

1 个答案:

答案 0 :(得分:2)

QCoreApplication::exec()方法本身负责发出aboutToQuit信号(至少从Qt 4.x开始)。由于您使用自己的简单事件循环绕过exec(),因此永远不会发出此信号。

exec() documentation建议使用不同的方法,而不是重新实施QCoreApplication

  

要使您的应用程序执行空闲处理(即,在没有挂起事件时执行特殊功能),请使用QTimer并暂停0。

我对Gevent一无所知,但您可以尝试使用计时器通过事件循环的每次运行来触发对gevent.sleep(0.01)的调用。这样,您可以确定您没有规避exec()实施的任何内置行为。