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

How to trigger aboutToQuit signal manually in PySide

我正在尝试基于 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_()

当我单击主 window 中的 X 按钮时,将调用 on_exit() 函数并且 bye... 字符串也会打印到控制台。

为了支持 Gevent,我需要在 app.exec_() 循环中的某处插入一个 gevent.sleep(0.01),所以我定义了以下函数:

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 的 greenlets 像预期的那样并行工作。

唯一的问题是,当我单击主 window 上的 X 按钮时,Qt 应用程序终止(window 已关闭)但是 on_exit() 函数没有被调用,因此剩下的 greenlets 继续工作。如何通过 QtGui.QApplication()app)对象手动检测主 window 的 X 按钮的点击事件?

编辑

考虑到已接受答案中的建议,工作实施如下:

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

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

re-implement exec() QCoreApplication documentation 推荐了一种不同的方法:

To make your application perform idle processing (i.e. executing a special function whenever there are no pending events), use a QTimer with 0 timeout.

我对 Gevent 一无所知,但您可以尝试使用计时器通过事件循环在每个 运行 中触发对 gevent.sleep(0.01) 的调用。这样,您就可以确定自己没有规避 exec().

实施的任何 built-in 行为