如何在 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 行为
我正在尝试基于 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()
.