为了初步实现QTreeWidget编辑项时检测当前输入是否与已有项冲突,如果冲突则提示,并且无法通过Enter键提交。
1、相关类及函数
QStyledItemDelegate
createEditor(self, parent: QWidget, option: QStyleOptionViewItem, index: QModelIndex)
eventFilter(self, object: QObject, event: QEvent)
关于QStyledItemDelegate相关内容,可以参考Qt61 视图中的委托1_qtreewidget::commitdata校验 阻止closeeditor-CSDN博客
实战PyQt5: 066-Model-View框架中的Delegate类_python qstyleditemdelegate 代理类创建 qdoublespinxbox-CSDN博客
2、相关代码
由于需要在编辑过程中提示当前输入是否与现有菜单中的名称重复,且当内容重复时不允许提交,需自定义QStyledItemDelegate,这里自定义QStyledItemDelegate的目的是为编辑器添加我们需要的功能,包括利用setToolTip设置提示,以及限制回车键提交,具体代码如下:
class proItemDelegate(QStyledItemDelegate):
def __init__(self, parent=None) -> None:
super(proItemDelegate, self).__init__(parent)
self.check_flag = True # 用以标记是否通过检测
self.old_name_list = [] # 存储当前菜单中的名称
self.initName = None # 记录初始传入名称,与初始名称相同不算重复
self.editor = None # 存储editor以便关联textChanged事件
def createEditor(self, parent: QWidget, option: QStyleOptionViewItem, index: QModelIndex) -> QWidget:
'''
创建编辑器
'''
print('createEditor')
# 获取初始值以及当前名称列表
self.initName = index.data()
self.old_name_list = self.getOldNameList()
# 创建编辑器
self.editor = QLineEdit(parent)
self.editor.textChanged.connect(self.checkNames) # 值变化时校核
return self.editor
def checkNames(self, text: str):
'''
textChanged触发函数,检查名称是否重复,并标记结果
'''
if text in self.old_name_list:
self.editor.setToolTip('与现有名称重复,请修改')
self.check_flag = False
else:
self.editor.setToolTip('')
self.check_flag = True
def getOldNameList(self)->list:
'''
根据自己项目实际情况实现获取现有名称的函数
'''
pass
def eventFilter(self, object: QObject, event: QEvent) -> bool:
# 由于输入框通过回车键提交
if type(object) == QLineEdit and event.type() == QEvent.KeyPress:
keyEvent = QKeyEvent(event) # 转换为QKeyEvent,用以匹配按键
# 经过测试发现回车对应的是Qt.Key_Return,并不是想象中的Qt.Key_Enter
if keyEvent.key() == Qt.Key_Enter or keyEvent.key() == Qt.Key_Return:
if not self.check_flag: return False
return super().eventFilter(object, event)
在QTreeWidget设置自定义的类
class ProMenu(QTreeWidget):
def __init__(self, pid=0, parent=None):
super(ProMenu, self).__init__(parent)
# 内容
self.initContent()
def initContent(self):
# 自定义委托
self.itemDelegate = proItemDelegate(self)
self.setItemDelegate(self.itemDelegate)