我正在尝试实现一个简单、轻量级的系统来记录 Qt GUI 事件并从脚本中回放它们。我认为使用 Qt 的事件系统的魔力这将是相当简单的,但我遇到了一个我不明白的问题。
这是我正在做的事情的快速总结:
记录:
我QApplication.instance().eventFilter()
用来捕获我感兴趣的所有 GUI 事件*并将它们保存到 Python 脚本中,其中每个步骤看起来像这样:
obj = get_named_object('MainWindow.my_menubar')
recorded_event = QMouseEvent(2, PyQt4.QtCore.QPoint(45, 8), 1, Qt.MouseButtons(0x1), Qt.KeyboardModifiers(0x0))
post_event(obj, recorded_event)
回放:
我只是在工作线程(非 GUI )中执行上面的脚本。(我不能使用 GUI 线程,因为我想继续向应用程序发送脚本事件,即使在模式对话框事件循环运行时阻塞了“主”事件循环。)
重要的事情发生在我的post_event()
函数中,它需要做两件事:
- 首先,打电话
QApplication.postEvent(obj, recorded_event)
- 等待所有事件完成处理:**
- 将特殊事件发布到
obj
正在运行的同一事件循环中。 - 处理特殊事件时:
- 称呼
QApplication.processEvents()
- 设置一个标志,告诉播放线程可以继续
- 称呼
- 将特殊事件发布到
在第二部分完成后,我的期望是第一部分(录制的事件)的所有效果都已完成,因为特殊事件在录制事件之后排队。
整个系统似乎对鼠标事件、按键事件等都很好。但是QAction
当我尝试为我的 main 播放事件时,我遇到了处理程序的问题QMenuBar
。
无论我尝试什么,似乎我都无法强制我的播放线程阻止QAction.triggered
由于单击我的QMenu
项目而导致的所有处理程序的完成。据我所知,在处理程序完成之前QApplication.processEvents()
返回。QAction
QMenu
小部件或信号是否有什么特别之处会破坏和/或QAction
的正常规则? 我需要一种方法来阻止我的处理程序的完成。QApplication.postEvent()
QApplication.processEvents()
QMenu
QAction
[*] 并非每个事件都被记录下来。我只记录spontaneous()
事件,也过滤掉一些其他类型(例如Paint
事件和普通的鼠标移动)。
[**] 这很重要,因为脚本中的下一个事件可能引用由上一个事件创建的小部件。