c++ - Qt GUI事件记录和回放

标签 c++ python qt pyqt qt-events

我正在尝试实现一个简单、轻量级的系统来记录 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 处理程序出现了问题我的主要 QMenuBar 的事件。

无论我尝试什么,似乎我无法强制我的播放线程阻塞以完成所有 QAction.triggered 处理程序我的 QMenu 项。据我所知,QApplication.processEvents() QAction 处理程序完成之前返回。

QMenu 小部件或 QAction 信号是否有一些特殊之处打破了 QApplication.postEvent() 和/或 的正常规则>QApplication.processEvents()? 我需要一种方法来阻止完成我的 QMenuQAction 处理程序。

[*] 并非每个事件都被记录下来。我只记录 spontaneous() 事件,我还过滤掉了一些其他类型(例如 Paint 事件和普通鼠标移动)。

[**] 这很重要,因为脚本中的下一个事件可能引用由上一个事件创建的小部件。

最佳答案

我认为您的问题可能最好通过使用 QFuture 和 QFutureWatcher 来解决(也就是说,如果您对线程使用 QtConcurrent 命名空间,而不是 QThreads)。基本上,Qt 事件处理系统不一定按事件发布的顺序处理事件。如果您需要阻塞直到某个 Action 完成,并且您在单独的线程中执行该 Action ,您可以使用 QtConcurrent::run() 返回的 QFuture 对象和 QFutureWatcher 来阻塞直到该特定线程完成其处理.

还有一点需要考虑的是您处理事件的方式。当您使用 QApplication.postEvent() 时,您创建的事件会添加到接收者的事件队列中,以便稍后处理。在幕后,Qt 可以重新排序和压缩这些事件以节省处理器时间。我怀疑这更多是你的问题。

在处理播放的函数中,考虑使用 QCoreApplication::processEvents(),它在所有事件处理完成之前不会返回。 QCoreApplication 的文档是 here.

关于c++ - Qt GUI事件记录和回放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15784719/

相关文章:

c++ - 使用 STL 对两个集合的并集元素进行计数

python - 是否有从 Python 的 OSError 获取信息的跨平台方式?

python - Selenium WebDriver等待但仍然是 "Element is not clickable at point"

c++ - 带有 Qt 对象的 Cmake 库?

c++ - 如何创建 boost::unordered_map 的子类?

c++ - MS Detours 2.1 - 从堆栈中弹出

c++ - 在头文件中声明一个返回二维数组的函数?

python - Numpy 如何在矢量化中排除数组?

c++ - QFile不读取文件

qt - 如何使 QLabel 背景半透明?