概要
对于QLineEdit 单行编辑组件,我们可能需要自定的条件激活编辑模式并关闭它,而LineEdit并没提供相关方法,这就要求我们对它进行重写
以下是对QLineEdit左键双击激活编辑,右键关闭的实现:
整体架构流程
from PySide6.QtCore import Qt
from PySide6.QtGui import QFont, QMouseEvent, QFocusEvent
from PySide6.QtWidgets import QApplication,QLineEdit,QWidget,QVBoxLayout,QPushButton
class lineEdit(QLineEdit):
def __init__(self):
super().__init__()
self.setPlaceholderText('请输入:')
self.setFont(QFont('sumHei,8'))
self.setReadOnly(True) #设置只读
self.resize(250,50)
self.setContextMenuPolicy(Qt.ContextMenuPolicy.NoContextMenu) #关闭右键上下菜单
def mousePressEvent(self, arg__1: QMouseEvent) -> None: #单击
if arg__1.button() == Qt.MouseButton.RightButton: #右键点击
self.setReadOnly(True)
def mouseDoubleClickEvent(self, arg__1:QMouseEvent) -> None: #双击
if arg__1.button() == Qt.MouseButton.LeftButton: #左键双击
self.setReadOnly(False)
super().mouseDoubleClickEvent(arg__1)
def focusOutEvent(self, arg__1: QFocusEvent) -> None: #失去焦点
self.setReadOnly(True)
super().focusOutEvent(arg__1)
if __name__ == '__main__':
app = QApplication([])
window = QWidget()
layout = QVBoxLayout(window)
layout.addWidget(lineEdit())
layout.addWidget(QPushButton('点击我'))
window.show()
app.exec()
控件方法解释
- mousePressEvent 鼠标点击事件 通过QMouseEvent可以获取具体点击按钮,鼠标坐标等
- mouseDoubleClickEvent 鼠标双击事件
- focusInEvent 获取焦点事件 通过QFocusEvent的reason()获取焦点原因(无法具体按键)
- focusOutEvent 失去焦点事件
- setReadOnly(bool) 设置只读(True)
技术细节
- QLineEdit正常情况下是自带右键菜单,我们想右键友好关闭编辑模式,还是最好关闭它
- QLineEdit在实现激活编辑模式的流程,并不是我们以为的那样:通过鼠标事件去实现。而是通过判断控件是否有焦点(可以是鼠标,按键等),其实它的编辑模式是一直处于激活状态,只是我们并没有对它进行聚焦操作,打个比方:它就像安卓后台应用一样随叫随到,一直处于开着的状态,只要我们激活它的前台状态,就可以继续使用(这里你可以试着把__init__中设置只读删除,在加个按钮在窗口上试着点击它们,一切就真相大白了)。
- 如果QLineEdit有父类,也可以通过eventFilter事件过滤来达到该效果
def eventFilter(self, object: QObject, event: QEvent) -> bool:
if object == self.LineEdit and event.type() == QEvent.Type.FocusOut:
self.LineEdit.setReadOnly(True)
- 存在父类时可能导致鼠标样式无法正确改变,我们需要手动改变它:
- self.setCursor(Qt.CursorShape.IBeamCursor) #编辑时鼠标样式(|)
- self.setCursor(Qt.CursorShape.ArrowCursor) #正常样式
小结
本章中我们通过重写QlineEdit的鼠标点击、双击事件和失去焦点事件,并使用现有控件方法,实现了自定义激活编辑和退出,如果有其他要求也可以试着从focusIn(out)Event等事件进行自定义。