Pyqt Validity Check On Qtreewidgetitem
Solution 1:
I've found a solution:
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
classTreeWidgetDelegate(QItemDelegate):
def__init__(self, parent=None):
QItemDelegate.__init__(self, parent=parent)
defcreateEditor(self, parent, option, index):
editor = QLineEdit(parent)
# allow only these chars
reg=QRegExp('[A-z0-9\[\]_-]+')
regvd=QRegExpValidator(reg)
editor.setValidator(regvd)
return editor
classMainWindow(QMainWindow):
def__init__(self):
super(QMainWindow, self).__init__()
frame=QWidget()
self.setCentralWidget(frame)
hl=QVBoxLayout()
frame.setLayout(hl)
self.tree=QTreeWidget(self)
hl.addWidget(self.tree)
# assign custom delegate to treewidget
dele=TreeWidgetDelegate()
self.tree.setItemDelegate(dele)
# add treewidgetitemsfor ii inrange(5):
item=QTreeWidgetItem([str(ii)*3,])
self.tree.addTopLevelItem(item)
self.tree.itemDoubleClicked.connect(self.rename)
# QueuedConnection cures the editting failed issue
self.tree.itemChanged.connect(self.checkName, Qt.QueuedConnection)
self.show()
defgetSiblings(self,item):
siblings=[self.tree.topLevelItem(ii).data(0,0) for ii in \
range(self.tree.topLevelItemCount())]
item_text=item.data(0,0)
if item_text in siblings:
siblings.remove(item_text)
return siblings
defrename(self):
item=self.tree.selectedItems()
if item:
item=item[0]
item.setFlags(item.flags() | Qt.ItemIsEditable)
self.tree.scrollToItem(item)
self.tree.editItem(item)
defcheckName(self,item,column):
text=item.data(0,0)
siblings=self.getSiblings(item)
print('checkName: slibings:', siblings)
if text in siblings:
print('checkName: ivalid')
item.setData(0,0,'New_name_needed')
self.tree.editItem(item)
if __name__ == "__main__":
app = QApplication(sys.argv)
form = MainWindow()
form.show()
sys.exit(app.exec_())
It's still using a custom delegate to check for invalid characters. I tried adding the sibling conflict check in the delegate's editor, by subclassing QValidator
and providing it the current list of siblings. However this would perform on-the-fly validation rather than post-commit validation. For instance when checking for the 'abc' v.s. 'abc' conflict, I won't be able to type 'c' after 'ab', even though I meant to type 'abcd'.
I found this question regarding the edit: editting failed
error, and it seems that the Qt.QueuedConnection
does the trick. So the tree.itemChanged
is connected to a duplication check function, and if it fails the check, it prompts the user to re-enter name again. One can optionally popup a tooltip notifying the conflict.
May not be the ideal solution though.
Post a Comment for "Pyqt Validity Check On Qtreewidgetitem"