问题描述
我有一个名为 generate_input_event 的函数.我正在尝试使用此功能来模拟 QWebEngineView 中的按键.
I have a function named generate_input_event. I'm trying to use this function to simulate a keypress within a QWebEngineView.
def generate_input_event(window_id, key_code, modifiers, low_level_data, x, y): modifiers_flag = create_modifiers_flag(modifiers) logging.info("generate input, window: {} code: {}, modifiers {}".format( window_id, key_code, modifiers_flag)) event = QKeyEvent(QEvent.KeyPress, key_code, modifiers_flag) event.artificial = True event_window = window.get_window(window_id) QCoreApplication.sendEvent(event_window.qtwindow, event)
每当我运行我的程序并在我的 QWebEngineView 中突出显示一个输入字段,并调用 generate_input_event 时,预计它会将该字母输入到输入字段中.
Whenever I run my program and highlight an input field within my QWebEngineView, and invoke generate_input_event it is expected that it will type that letter into the input field.
我还设置了一个事件过滤器来捕获所有按键,除了我人工生成的按键.
I also set-up an event filter to capture everything all key presses EXCEPT for my artificially generated ones.
class EventFilter(QWidget): def __init__(self, parent=None): super(EventFilter, self).__init__(parent) qApp.installEventFilter(self) def eventFilter(self, obj, event): if (event.type() == QEvent.KeyPress and hasattr(event, 'artificial')): logging.info("artificial event") return False. # send to widget elif (event.type() == QEvent.KeyPress and not is_modifier(event.key())): modifiers = create_modifiers_list(event.modifiers()) key_string = create_key_string(event) key_code = event.key() logging.info("send code: {} string: {} modifiers {}".format( key_code, key_string, modifiers)) return True. # do not forward to widgets return False
但是,当我实际运行我的代码时,我得到以下输出:
However when I actually run my code, this is the following output I get:
INFO:root:send code: 65 string: a modifiers [''] INFO:root:generate input, window: 1 code: 65, modifiers <PyQt5.QtCore.Qt.KeyboardModifiers object at 0x106a4ea58> INFO:root:artificial event
输出看起来是正确的,但是,QWebEngineView 的输入字段实际上从来没有得到一个由 generate_input_event 人为生成的字母.
The output looks correct, HOWEVER, the input field of the QWebEngineView never actually gets a letter that was artificially generated by generate_input_event.
附:如果您出于上下文原因希望查看整个文件/项目,请在此处查看此分支/文件:https://github.com/atlas-engineer/next/blob/generate_events/ports/pyqt-webengine/utility.py
P.S. Should you wish to see the whole of the file/project for reasons of context, please look at this branch/file here: https://github.com/atlas-engineer/next/blob/generate_events/ports/pyqt-webengine/utility.py
推荐答案
可以通过以下最小示例演示发布和侦听 QWebengineview 事件的正确方法:
The correct way to post and listen to events for a QWebengineview can be demonstrated with the following minimal example:
from PyQt5 import QtCore, QtGui, QtWidgets, QtWebEngineWidgets from PyQt5.QtCore import Qt class ForwardKeyEvent(QtCore.QObject): def __init__(self, sender, receiver, parent=None): super(ForwardKeyEvent, self).__init__(parent) self.m_sender = sender self.m_receiver = receiver self.m_sender.installEventFilter(self) def eventFilter(self, obj, event): if self.m_sender is obj and event.type() == QtCore.QEvent.KeyPress: new_event = QtGui.QKeyEvent( QtCore.QEvent.KeyPress, 65, Qt.KeyboardModifiers(), "a", ) new_event.artificial = True QtCore.QCoreApplication.postEvent(self.m_receiver.focusProxy(), new_event) return True return False if __name__ == "__main__": import sys app = QtWidgets.QApplication(sys.argv) lineedit = QtWidgets.QLineEdit() lineedit.show() view = QtWebEngineWidgets.QWebEngineView() view.resize(640, 480) view.show() view.load(QtCore.QUrl("https://www.google.com/")) # RenderWidgetHostViewQtDelegateWidget is created after loading a page # so you must access it after load() or setHtml(). fe = ForwardKeyEvent(lineedit, view) sys.exit(app.exec_())