簡體   English   中英

Qt GUI事件錄制和播放

[英]Qt GUI event recording and playback

我正在嘗試實現一個簡單,輕量級的系統來記錄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)

回放:

我只是在一個worker( 非GUI )線程中執行上面的腳本。 (我不能使用GUI線程,因為我想繼續向應用程序發送腳本事件,即使在模式對話框eventloop運行時'main'eventloop被阻止。)

重要的東西發生在我的post_event()函數中,它需要做兩件事:

  • 首先,調用QApplication.postEvent(obj, recorded_event)
  • 等待所有事件完成處理:**
    • 將特殊事件發布到運行obj的同一事件循環中。
    • 處理特殊事件時:
      • 調用QApplication.processEvents()
      • 設置一個標志,告訴回放線程可以繼續

第二部分完成后,我的期望是第一部分(記錄的事件)的所有效果都已完成 ,因為特殊事件在記錄的事件之后排隊。

整個系統主要是似乎只是正常工作的鼠標事件,重要事件等,但我有一個問題QAction處理程序,當我試圖播放我的主要活動QMenuBar

無論我嘗試什么,似乎我都不能強制我的回放線程阻止完成因點擊我的QMenu項而產生的所有QAction.triggered處理程序 據我所知, QApplication.processEvents()QAction處理程序完成之前返回。

有關QMenu小部件或QAction信號的特殊內容QMenu違反了QApplication.postEvent()和/或QApplication.processEvents()的常規規則? 我需要一種方法來阻止我的QMenuQAction處理程序的完成。

[*]並非每個事件都被記錄下來。 我只記錄spontaneous()事件,我還過濾掉了一些其他類型(例如Paint事件和普通鼠標移動)。

[**]這很重要,因為腳本中的下一個事件可能引用上一個事件創建的窗口小部件。

我認為你的問題可能最好通過使用QFuture和QFutureWatcher來實現(也就是說,如果你為線程使用QtConcurrent命名空間而不是QThreads)。 基本上,Qt事件處理系統不一定按照發布的順序處理事件。 如果需要阻塞直到某個操作完成,並且您在單獨的線程中執行該操作,則可以使用QtConcurrent :: run()返回的QFuture對象與QFutureWatcher一起阻塞,直到該特定線程完成其處理。

還需要考慮的是處理事件的方式。 使用QApplication.postEvent()時,您創建的事件將添加到接收方的事件隊列中,以便稍后處理。 在幕后,Qt可以重新排序和壓縮這些事件以節省處理器時間。 我懷疑這更像是你的問題。

在處理回放的函數中,請考慮使用QCoreApplication :: processEvents(),它將在所有事件處理完畢后才返回。 QCoreApplication的文檔就在這里。

QMenu小部件和QAction信號是一個特例。 QMenu有一個exec()函數,通常用於彈出窗口。 我懷疑(但我不確定)QMenuBar在打開常規下拉菜單時會使用此機制。 文檔對此並不清楚,但Menus的行為很像對話框,因為它們阻止了所有其他用戶活動 - 除了通過給菜單提供自己的事件循環之外,Qt將如何做到這一點? 我無法填寫你帖子中信息的所有空白,但我看不到你的播放線程如何應對新的事件循環。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM