我通过覆盖类的KeyPressEvent
方法(从QWidget
继承)来捕获按键事件,但是我看不到ESCAPE和BACKSPACE键的按键 press 事件,以及C-x
或再次C-c
。我可以看到关键的 release 事件。谁抓住了他们?
class KeyCaptureWidget(QWidget):
# init…
def keyPressEvent(self, event):
key = event.key()
logging.info("key press: {}".format(key))
def keyReleaseEvent(self, event):
key_code = event.key()
logging.info("key release: {}".format(key_code))
C-x
和说C-b
之间的区别如下:
C-b
会打印:按下控件,按下b,释放b,释放控件。C-x
将打印:按下控件,[什么都没有],释放x,释放控件。在我的QWidget中,我使用了一个QVBoxLayout,其中放置了两个QWebEngine视图。我试图重写QWebEngineView的按键方法,但是它们似乎没有捕获任何东西(这是我所期望的行为)。
def __init__(self):
self.qtwindow = KeyCaptureWidget()
self.layout = QVBoxLayout()
self.view1 = QWebEngineView() # or a custom one to override keyPressEvent
# self.view2 = the same
self.layout.addWidget(self.view1)
self.layout.addWidget(self.view2)
self.qtwindow.setLayout(self.layout)
self.qtwindow.show()
我试图在我的QWidget类上使用事件过滤器来捕获这些消息,但是再次失败了:我只看到ESC或BACKSPACE的关键版本。
def __init__(self):
super().__init__()
self.installEventFilter(self)
def eventFilter(self, source, event):
logging.info("event filter: {}".format(event))
if event.type() == QEvent.KeyPress:
logging.info(" event filter key PRESS")
if event.type() == QEvent.KeyRelease:
logging.info(" event filter key RELEASE")
return True
我如何抓住他们?谢谢。
答案 0 :(得分:2)
事件不一定会在所有窗口小部件之间传播,如果窗口小部件消耗了事件,则事件将不再传播到父窗口。对于键盘事件,只有具有焦点的窗口小部件才会首先使用事件,在您的情况下,QWebEngineView会先使用它们,并阻止将其投影到其他窗口小部件中。如果要从窗口的键盘中听到事件,则必须使用QShortcuts,为此必须创建QShortcut:
QtGui.QKeySequence("Ctrl+C")
QtGui.QKeySequence("Ctrl+X")
QtGui.QKeySequence("Escape")
QtGui.QKeySequence("Backspace")
考虑到上述情况,解决方案是:
from PyQt5 import QtCore, QtGui, QtWidgets, QtWebEngineWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.m_view1 = QtWebEngineWidgets.QWebEngineView()
self.m_view2 = QtWebEngineWidgets.QWebEngineView()
self.m_view1.load(QtCore.QUrl("https://stackoverflow.com/questions/56890831"))
self.m_view2.load(QtCore.QUrl("https://doc.qt.io/"))
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(self.m_view1)
lay.addWidget(self.m_view2)
QtWidgets.QShortcut(
QtGui.QKeySequence("Ctrl+C"), self, activated=self.on_Ctrl_C
)
QtWidgets.QShortcut(
QtGui.QKeySequence("Ctrl+X"), self, activated=self.on_Ctrl_X
)
QtWidgets.QShortcut(
QtGui.QKeySequence("Escape"), self, activated=self.on_Escape
)
QtWidgets.QShortcut(
QtGui.QKeySequence("Backspace"), self, activated=self.on_Backspace
)
@QtCore.pyqtSlot()
def on_Ctrl_C(self):
print("Ctrl+C")
@QtCore.pyqtSlot()
def on_Ctrl_X(self):
print("Ctrl+X")
@QtCore.pyqtSlot()
def on_Escape(self):
print("Escape")
@QtCore.pyqtSlot()
def on_Backspace(self):
print("Backspace")
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.resize(640, 480)
w.show()
sys.exit(app.exec_())