我正在尝试编写一个pyqt5应用程序,该应用程序捕获某些击键,并用其他一些击键替换它们。由于我希望对整个应用程序进行此替换,因此我(也许是错误的(我需要在qApp
上进行事件过滤器。搜索后,我将此概念证明拼凑在一起:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt
# Keys to block
kmap = [Qt.Key_U,Qt.Key_I,Qt.Key_O,Qt.Key_P,Qt.Key_J,Qt.Key_K,Qt.Key_L,Qt.Key_M]
class Example(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
# The simplest UI
def initUI(self):
self.edit = QtWidgets.QTextEdit()
QtWidgets.qApp.installEventFilter(self)
self.setCentralWidget(self.edit)
# Window placement
self.show()
def sendkeys(self, char, modifier=Qt.NoModifier):
event = QtGui.QKeyEvent(QtCore.QEvent.KeyPress, 0, modifier, char)
QtCore.QCoreApplication.postEvent(self, event)
event = QtGui.QKeyEvent(QtCore.QEvent.KeyRelease, 0, modifier, char)
QtCore.QCoreApplication.postEvent(self, event)
def eventFilter(self, obj, event):
if type(event) == QtGui.QKeyEvent:
print("Normal stroke %d of type %s to %s" % (event.key(), str(event.type()), str(obj)))
if event.key() in kmap:
if type(obj) == QtWidgets.QTextEdit and obj.type() == QtCore.QEvent.KeyPress:
sendkeys("c")
return True
return super().eventFilter(obj, event)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
不幸的是,这无效。完全。
首先,即使我在记录后进行过滤,也会阻止和未阻止的键产生不同的事件:
Normal stroke 66 of type 51 to <PyQt5.QtGui.QWindow object at 0x7ff4800af948>
Normal stroke 66 of type 51 to <PyQt5.QtWidgets.QTextEdit object at 0x7ff4800af8b8>
Normal stroke 66 of type 6 to <PyQt5.QtGui.QWindow object at 0x7ff4800af948>
Normal stroke 66 of type 6 to <PyQt5.QtWidgets.QTextEdit object at 0x7ff4800af8b8>
Normal stroke 66 of type 7 to <PyQt5.QtGui.QWindow object at 0x7ff4800af948>
Normal stroke 66 of type 7 to <PyQt5.QtWidgets.QTextEdit object at 0x7ff4800af8b8>
Normal stroke 66 of type 7 to <__main__.Example object at 0x7ff4800af828>
Normal stroke 77 of type 51 to <PyQt5.QtGui.QWindow object at 0x7ff4800af948>
Normal stroke 77 of type 6 to <PyQt5.QtGui.QWindow object at 0x7ff4800af948>
Normal stroke 77 of type 7 to <PyQt5.QtGui.QWindow object at 0x7ff4800af948>
第二,sendkeys
不起作用 - 笔触永远不会出现。
我不太确定我在误会什么 - 任何指针?
如果您的目标是替换发送的击键,那么您必须做的就是将它们发送到同一对象,而是将它们发送到窗口:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt
# Keys to block
kmap = [Qt.Key_U,Qt.Key_I,Qt.Key_O,Qt.Key_P,Qt.Key_J,Qt.Key_K,Qt.Key_L,Qt.Key_M]
class Example(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
# The simplest UI
def initUI(self):
self.edit = QtWidgets.QTextEdit()
self.setCentralWidget(self.edit)
QtWidgets.qApp.installEventFilter(self)
# Window placement
self.show()
def sendkeys(self, obj, char, modifier=Qt.NoModifier):
event = QtGui.QKeyEvent(QtCore.QEvent.KeyPress, 0, modifier, char)
QtCore.QCoreApplication.postEvent(obj, event)
event = QtGui.QKeyEvent(QtCore.QEvent.KeyRelease, 0, modifier, char)
QtCore.QCoreApplication.postEvent(obj, event)
def eventFilter(self, obj, event):
if event.type() == QtCore.QEvent.KeyPress and isinstance(obj, QtWidgets.QTextEdit):
print("Normal stroke %d of type %s to %s" % (event.key(), str(event.type()), str(obj)))
if event.key() in kmap:
self.sendkeys(obj, "c")
return True
return super().eventFilter(obj, event)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())