Qwidget 的 KeyPressEvent 不起作用?
KeyPressEvent with Qwidget is not working?
如果我按任意键,什么也不会发生。如何实施?我注意到如果我按下某个键,(起初 time/Very Beggning/first 字符),需要更多时间来显示 textbox.How 中按下的字符来解决它?
from PyQt5 import QtWidgets,QtCore,QtGui
class MyKey(QtWidgets.QWidget):
def __init__(self):
super(). __init__()
self.setWindowTitle(" My Key Board")
self.ui()
def ui(self):
self.tb = QtWidgets.QLineEdit()
self.vb = QtWidgets.QVBoxLayout()
self.vb.addWidget(self.tb)
self.setLayout(self.vb)
def keyPressEvent(self, e):
print("key pressed")
print(e.key())
if type(e) == QtGui.QKeyEvent:
if e.key() == QtCore.Qt.Key_A:
print("ypu pressed 'A'")
if __name__ == "__main__":
import sys
myapp = QtWidgets.QApplication(sys.argv)
mywindow = MyKey()
mywindow.show()
sys.exit(myapp.exec_())
在 Qt 中,KeyPressEvent 仅发送到具有焦点的小部件,如果它使用它,则事件不会发送到父小部件,否则父小部件也会收到通知。
在这种情况下,QLineEdit 是具有焦点的小部件并消耗具有文本、数字和一些特殊键的事件,因此在这些情况下不会通知父小部件。 QLineEdit 未使用其他键,例如 F2、Escape 等,这些键由父小部件接收。
如果你想听一个特殊的键或键的组合,那么你必须使用一个 QShortcut
但是因为 OP 想听所有的事件,那么一个可能的解决方案是安装一个事件过滤器到与window相关联的QWindow,如果它在window获得焦点时接收到键盘事件,则无论哪个widget获得焦点。
from PyQt5 import QtWidgets, QtCore, QtGui
class MyKey(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle(" My Key Board")
self.ui()
def ui(self):
self.tb = QtWidgets.QLineEdit()
vb = QtWidgets.QVBoxLayout(self)
vb.addWidget(self.tb)
def handle_key_press(self, key, text):
if key == QtCore.Qt.Key_A:
print("ypu pressed 'A'")
class KeyHelper(QtCore.QObject):
key_pressed = QtCore.pyqtSignal(int, str)
def __init__(self, window):
super().__init__(window)
self._window = window
self.window.installEventFilter(self)
@property
def window(self):
return self._window
def eventFilter(self, obj, event):
if obj is self._window and event.type() == QtCore.QEvent.KeyPress:
self.key_pressed.emit(event.key(), event.text())
return super().eventFilter(obj, event)
if __name__ == "__main__":
import sys
myapp = QtWidgets.QApplication(sys.argv)
mywindow = MyKey()
mywindow.show()
helper = KeyHelper(mywindow.windowHandle())
helper.key_pressed.connect(mywindow.handle_key_press)
sys.exit(myapp.exec_())
如果我按任意键,什么也不会发生。如何实施?我注意到如果我按下某个键,(起初 time/Very Beggning/first 字符),需要更多时间来显示 textbox.How 中按下的字符来解决它?
from PyQt5 import QtWidgets,QtCore,QtGui
class MyKey(QtWidgets.QWidget):
def __init__(self):
super(). __init__()
self.setWindowTitle(" My Key Board")
self.ui()
def ui(self):
self.tb = QtWidgets.QLineEdit()
self.vb = QtWidgets.QVBoxLayout()
self.vb.addWidget(self.tb)
self.setLayout(self.vb)
def keyPressEvent(self, e):
print("key pressed")
print(e.key())
if type(e) == QtGui.QKeyEvent:
if e.key() == QtCore.Qt.Key_A:
print("ypu pressed 'A'")
if __name__ == "__main__":
import sys
myapp = QtWidgets.QApplication(sys.argv)
mywindow = MyKey()
mywindow.show()
sys.exit(myapp.exec_())
在 Qt 中,KeyPressEvent 仅发送到具有焦点的小部件,如果它使用它,则事件不会发送到父小部件,否则父小部件也会收到通知。
在这种情况下,QLineEdit 是具有焦点的小部件并消耗具有文本、数字和一些特殊键的事件,因此在这些情况下不会通知父小部件。 QLineEdit 未使用其他键,例如 F2、Escape 等,这些键由父小部件接收。
如果你想听一个特殊的键或键的组合,那么你必须使用一个 QShortcut
但是因为 OP 想听所有的事件,那么一个可能的解决方案是安装一个事件过滤器到与window相关联的QWindow,如果它在window获得焦点时接收到键盘事件,则无论哪个widget获得焦点。
from PyQt5 import QtWidgets, QtCore, QtGui
class MyKey(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle(" My Key Board")
self.ui()
def ui(self):
self.tb = QtWidgets.QLineEdit()
vb = QtWidgets.QVBoxLayout(self)
vb.addWidget(self.tb)
def handle_key_press(self, key, text):
if key == QtCore.Qt.Key_A:
print("ypu pressed 'A'")
class KeyHelper(QtCore.QObject):
key_pressed = QtCore.pyqtSignal(int, str)
def __init__(self, window):
super().__init__(window)
self._window = window
self.window.installEventFilter(self)
@property
def window(self):
return self._window
def eventFilter(self, obj, event):
if obj is self._window and event.type() == QtCore.QEvent.KeyPress:
self.key_pressed.emit(event.key(), event.text())
return super().eventFilter(obj, event)
if __name__ == "__main__":
import sys
myapp = QtWidgets.QApplication(sys.argv)
mywindow = MyKey()
mywindow.show()
helper = KeyHelper(mywindow.windowHandle())
helper.key_pressed.connect(mywindow.handle_key_press)
sys.exit(myapp.exec_())