我正在使用 PyQt5 在 Python 上为客户端编写聊天 gui。 我有一个 QTextEdit,客户端可以在其中写入消息。 我不想知道当焦点位于 QTextEdit 上时何时按下“Enter”键。
我尝试使用 installEventFilter 函数,但它检测到除 QTextEdit 之外的所有其他小部件上按下的按键。 我可以做什么来解决这个问题?
def initUI(self):
# ...
self.text_box = QtWidgets.QTextEdit(self)
self.installEventFilter(self)
# ...
def keyPressEvent(self, qKeyEvent):
print(qKeyEvent.key())
if qKeyEvent.key() == Qt.Key_Return:
if self.text_box.hasFocus():
print('Enter pressed')
当您覆盖 keyPressEvent 时,您正在监听窗口的事件,而是将 eventFilter 安装到 QTextEdit,而不是像您在代码中所做的那样安装到窗口,并检查作为参数传递的对象是否是 QTextEdit:
def initUI(self):
# ...
self.text_box = QtWidgets.QTextEdit(self)
self.text_box.installEventFilter(self)
# ...
def eventFilter(self, obj, event):
if event.type() == QtCore.QEvent.KeyPress and obj is self.text_box:
if event.key() == QtCore.Qt.Key_Return and self.text_box.hasFocus():
print('Enter pressed')
return super().eventFilter(obj, event)
如果你决定使用 QTextEdit,@eyllanesc 的答案非常好。
如果您可以摆脱 QLineEdit 及其限制,则可以使用 returnPressed() 信号。 QLineEdit 的最大缺点是您仅限于一行文本。并且没有自动换行。但优点是您不必搞乱 eventFilters 或过多考虑 keyPress 信号如何通过应用程序中的所有小部件。
这是一个从一个 QLineEdit 复制到另一个 QLineEdit 的最小示例:
import sys
from PyQt5.QtWidgets import *
class PrintWindow(QMainWindow):
def __init__(self):
super().__init__()
self.left=50
self.top=50
self.width=300
self.height=300
self.initUI()
def initUI(self):
self.setGeometry(self.left,self.top,self.width,self.height)
self.line_edit1 = QLineEdit(self)
self.line_edit1.move(50, 50)
self.line_edit1.returnPressed.connect(self.on_line_edit1_returnPressed)
self.line_edit2 = QLineEdit(self)
self.line_edit2.move(50, 100)
self.show()
def on_line_edit1_returnPressed(self):
self.line_edit2.setText(self.line_edit1.text())
if __name__ == '__main__':
app = QApplication(sys.argv)
window = PrintWindow()
sys.exit(app.exec_())
在此示例中,我手动连接到第 22 行中的信号 (
self.line_edit1.returnPressed.connect
)。如果您使用的是 ui 文件,则可以省略此连接,您的程序将自动调用 on__returnPressed 方法。
当您覆盖 keyPressEvent 时,您正在监听窗口的事件,而是将 eventFilter 安装到 QTextEdit,而不是像您在代码中所做的那样安装到窗口,并检查作为参数传递的对象是否是 QTextEdit:
def initUI(self):
# ...
self.text_box = QtWidgets.QTextEdit(self)
self.text_box.installEventFilter(self)
# ...
def eventFilter(self, obj, event):
if event.type() == QtCore.QEvent.KeyPress and obj is self.text_box:
if event.key() == QtCore.Qt.Key_Return and self.text_box.hasFocus():
print('Enter pressed')
return True
return False
这是建立在@eyllanesc 的答案和@Daniel Segal 面临的问题的基础上的。将正确的返回值添加到
eventFilter
可以解决问题。
对于那些使用
PyQt6
的人,这里是代码:
import PyQt6.QtCore
import PyQt6.QtWidgets
def initUI(self):
# ...
self.text_box = QtWidgets.QTextEdit(self)
self.text_box.installEventFilter(self)
# ...
def eventFilter(self, obj, event):
if event.type() == QtCore.QEvent.Type.KeyPress and obj is self.text_box:
if event.key() == QtCore.Qt.Key.Key_Return and self.text_box.hasFocus():
print('Enter pressed')
return super().eventFilter(obj, event)
QtCore.QEvent.KeyPress
更改为 QtCore.QEvent.Type.KeyPress
,QtCore.Qt.Key_Return
更改为 QtCore.Qt.Key.Key_Return
。