基本介绍
QLineEdit本身支的信号函数一共有六个,但其中只有returnPressed的响应,并没有对其他按键的响应。参见:QLineEdit 信号函数总结,https://blog.csdn.net/u013687602/article/details/19968185
·void cursorPositionChanged( intold, intnew )
当鼠标移动时发出此信号,old为先前的位置,new为新位置。
·void editingFinished()
当按返回或者回车键时,或者行编辑失去焦点时,发出此信号。
注意:当QLineEdit设置了validator() orinputMask()函数,验证器or输入掩码,并按了返回或回车键,信号只有在 输入内容符合输入掩码 或验证器返回 QValidator::Acceptable时 发出。
· void returnPressed()
当 返回或回车键按下时发出此信号,
注意:当QLineEdit设置了validator() orinputMask()函数,验证器or输入掩码,并按了返回或回车键,信号只有在 输入内容符合输入掩码 或验证器返回 QValidator::Acceptable时 发出。
· void selectionChanged()
当选文本改变时,发出此信号。
· void textChanged( const QString &text )
当QLineEdit中的文本改变时,发出此信号,text是新的文本。当通过程序改变文本时,也会触发此信号,例如,setText()
· void textEdited( const QString &text )
当QLineEdit中的文本改变时,发出此信号,text是新的文本。当通过程序改变文本时,不会触发此信号。这6个信号在python中的使用参考“PyQt5 QLineEdit控件信号使用”一文,https://blog.csdn.net/u013934107/article/details/94599494
le.textEdited.connect(lambda val:print("文本框编辑的时候",val))#文本框编辑事件
le.textChanged.connect(lambda val:print("文本框内容发生改变",val))#文本框改变事件
le.returnPressed.connect(lambda:print("回车键被按下"))
le.returnPressed.connect(lambda:le2.setFocus())
le.editingFinished.connect(lambda:print("结束编辑"))
le.cursorPositionChanged.connect(lambda old_Pos,new_Pos:print(old_Pos,new_Pos))#焦点发生改变
le.selectionChanged.connect(lambda:print("选中文本发生改变",le.selectedText()))#选中文本发生改变事件
通过installEventFilter响应按键
由上一小节可知,QLineEdit控件本身并不支持单独响应tab键、上下左右方向键。通过搜索,我们看到可以通过installEventFilter的方式来实现这一功能。
https://stackoverflow.com/questions/2078842/qlineedit-how-to-handle-up-and-down-arrows
该文虽然和本文中我们遇到的问题很一致,从问答中我们可以进一步确认QLineEdit对于tab键及方向键,确实没有提供类似于returnPressed这样的信号函数。尽管回答中提供了通过installEventFilter实现功能的思路,但是对于具体的实现描述不多。因此我们继续以installEventFilter为关键字进行搜索。
https://stackoverflow.com/questions/25275974/make-qlineedit-detect-tab-key-press-event
该文介绍了C++中,介绍了通过installEventFilter方式和继承QLineEdit 的方式来实现tab按键检测的方式。同时演示了自定义eventFilter()函数的写法。
https://stackoverflow.com/questions/50768366/installeventfilter-in-pyqt5
该文介绍了在python中,通过调用QLineEdit对象实例的installEventFilter方法来监听按键。特别地,该文演示了python中自定义eventFilter()函数的写法。该文中,给installEventFilter函数传递的self对象同时是Ui_cortes2的实例,但这并不是必须的。下文会有说。
https://programtalk.com/python-examples/PyQt5.QtWidgets.QApplication.instance.installEventFilter/
https://programtalk.com/vs2/python/13927/frescobaldi/frescobaldi_app/gadgets/customtooltip.py/
通过阅读这段代码,我们可以知道,给installEventFilter函数传递的类对象只需要是QObject的实例对象即可。同时该代码还提示我们,除了QEvent.KeyPress外,installEventFilter还可以监听FocusIn、Leave等事件。
代码实现
由于我们在python环境下使用Qt,是通过designer来设计界面的,并通过命令将ui命令转为py文件(pyuic5 -o main_ui.py fp_dev_tool.ui)。所以我们没有走继承QLineEdit的这种方式,而是采用installEventFilter的方式来实现我们的需求。下面是我们对QLineEdit的一个封装。
from PyQt5.QtCore import QEvent, QObject
class CustomQLineEditWrapper(QObject):
def __init__(self, editor):
# installEventFilter 依赖QObject,因此必须先调用父类构造函数
super().__init__()
self.editor = editor
self.editor.installEventFilter(self)
self.keyMap = {}
def setKeyPressCallback(self, key, callback):
self.keyMap[key] = callback
# 返回True表示将此消息消耗掉,返回False则不会
def eventFilter(self, obj, ev):
if obj is not self.editor:
return False
if ev.type() != QEvent.KeyPress:
return False
if ev.key() in self.keyMap:
self.keyMap[ev.key()]()
return True
return False#pyuic5 -o main_ui.py fp_dev_tool.ui
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget
from PyQt5.QtWidgets import QMessageBox
import sys
import main_ui
from custom_qlineedit_wrapper import *
class FfDevToolWindow(main_ui.Ui_MainWindow):
def setupUi(self, window):
super().setupUi(window)
self.cmdLineEdit.setFocus()
self.cmdLineEdit.returnPressed.connect(self.returnPressed)
self.lineEditor = CustomQLineEditWrapper(self.cmdLineEdit)
self.lineEditor.setKeyPressCallback(Qt.Key_Escape, lambda:self.cmdLineEdit.setText(""))
self.lineEditor.setKeyPressCallback(Qt.Key_Up, self.upPressed)
self.lineEditor.setKeyPressCallback(Qt.Key_Down, self.downPressed)
def upPressed(self):
QMessageBox.information(QWidget(), "标题", "key up", QMessageBox.Yes | QMessageBox.No)
def downPressed(self):
QMessageBox.information(QWidget(), "标题", "key down", QMessageBox.Yes | QMessageBox.No)
def returnPressed(self):
self.cmdLineEdit.setText("")
if __name__ == '__main__':
app = QApplication(sys.argv)
MainWindow = QMainWindow()
ui = FfDevToolWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())其他资料
Qt::Key键盘按键详细说明,https://blog.csdn.net/judgejames/article/details/93191524
Qt::Key_Escape | 0x01000000 | Esc键 |
Qt::Key_Tab | 0x01000001 | Tab键 |
Qt::Key_Backtab | 0x01000002 | Tab补全键 |
Qt::Key_Return | 0x01000004 | Return键 |
Qt::Key_Enter | 0x01000005 | 回车键 |
Qt::Key_Left | 0x01000012 | ← |
Qt::Key_Up | 0x01000013 | ↑ |
Qt::Key_Right | 0x01000014 | → |
Qt::Key_Down | 0x01000015 | ↓ |
其中,Key_Enter是小键盘的确认键,Key_Return是大键盘的回车键。参见:https://blog.csdn.net/qq_37887537/article/details/79089288