我正在构建一个QTreeWidget,在其中实现添加新项和重命名功能。我想检查一下用户给出的新名称的有效性,包括:
QRegExpValidator
添加QItemDelegate
并将新委托分配给QTreeWidget
来实现。在以下是我目前的尝试:
import sys
from PyQt5.QtWidgets import QItemDelegate, QTreeWidget, QVBoxLayout, QLineEdit,\
QMainWindow, QWidget, QTreeWidgetItem, QApplication
from PyQt5.QtCore import QRegExp, Qt
from PyQt5.QtGui import QRegExpValidator
class TreeWidgetDelegate(QItemDelegate):
def __init__(self, parent=None):
QItemDelegate.__init__(self, parent=parent)
def createEditor(self, parent, option, index):
editor = QLineEdit(parent)
reg=QRegExp('[A-z0-9\[\]_-]+')
vd=QRegExpValidator(reg)
editor.setValidator(vd)
return editor
class MainWindow(QMainWindow):
def __init__(self):
super(self.__class__, self).__init__()
frame=QWidget()
self.setCentralWidget(frame)
hl=QVBoxLayout()
frame.setLayout(hl)
self.tree=QTreeWidget(self)
mydele=TreeWidgetDelegate()
self.tree.setItemDelegate(mydele)
hl.addWidget(self.tree)
# add treewidgetitems
for ii in range(5):
item=QTreeWidgetItem([str(ii),])
self.tree.addTopLevelItem(item)
self.tree.itemDoubleClicked.connect(self.rename)
self.tree.itemChanged.connect(self.checkString)
dele=self.tree.itemDelegate()
print('dele',dele)
self.show()
def rename(self):
item=self.tree.selectedItems()
if item:
item=item[0]
item.setFlags(item.flags() | Qt.ItemIsEditable)
self.tree.scrollToItem(item)
self.tree.editItem(item)
def checkString(self,item,column):
text=item.data(0,column)
print('newname:',text)
siblings=[self.tree.topLevelItem(ii).data(0,0) for ii in \
range(self.tree.topLevelItemCount())]
print('siblings:',siblings)
if text in siblings:
print('invalid name')
# this gives "edit: editing failed"
self.tree.editItem(item)
if __name__ == "__main__":
app = QApplication(sys.argv)
form = MainWindow()
form.show()
sys.exit(app.exec_())
特别是,我正在连接tree.itemChanged.connect(self.checkString)
,并且checkString()
检查名称冲突。但是,当检测到冲突时,我不知道如何恢复旧名称,重新进入编辑模式,让用户重新命名。tree.editItem(item)
将抛出一个错误
一。我想这会再次触发信号,最终形成一个无休止的循环?在
我发现了PyQt - Using Multiple Validators for Item Delegates相关,但没有给出答案,只是在注释中建议应该将QValidator
子类化,以便在同一个regex中处理名称冲突检测。不知道怎么做,验证器是在那些QTreeWidgetItems
之前创建和分配的,不是吗?在
还有这个问题Make QTreeWidgetItem unique among siblings。没有人回答。在
我找到了一个解决方案:
它仍在使用自定义委托来检查无效字符。我尝试在委托的编辑器中添加同级冲突检查,方法是将
QValidator
子类化并向其提供当前同级列表。但是,这将执行动态验证,而不是提交后验证。例如,在检查“abc”与“abc”冲突时,我无法在“ab”后面键入“c”,即使我本想键入“abcd”。在我发现了this question关于}起了作用。因此,
edit: editting failed
错误,似乎{tree.itemChanged
连接到一个重复检查函数,如果检查失败,它会提示用户重新输入名称。可以选择弹出一个工具提示来通知冲突。在但可能不是理想的解决方案。在
相关问题 更多 >
编程相关推荐