[英]How to check if QTreeWidgetItem is checked or unchecked? (PyQt4/Python)
[英]PyQt validity check on QTreeWidgetItem
我正在构建一个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)
将引发错误
edit: editing failed
。 我想那会再次触发信号并最终陷入无尽的循环?
我发现PyQt-为项目委托使用多个验证器相关,但是没有给出答案,只是在注释中提出了一个建议,即应该将QValidator
子类QValidator
以在同一正则表达式中处理名称冲突检测。 不知道如何执行此操作,在这些QTreeWidgetItems
之前创建并分配了验证器,不是吗?
这个问题也使QTreeWidgetItem在同级中唯一 。 没有人回答。
我找到了一个解决方案:
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)
# allow only these chars
reg=QRegExp('[A-z0-9\[\]_-]+')
regvd=QRegExpValidator(reg)
editor.setValidator(regvd)
return editor
class MainWindow(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 treewidgetitems
for ii in range(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()
def getSiblings(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
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 checkName(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_())
它仍在使用自定义委托来检查无效字符。 我尝试通过将QValidator
子类QValidator
并为其提供当前的同级列表,在委托的编辑器中添加同级冲突检查。 但是,这将执行即时验证,而不是提交后验证。 例如,当检查“ abc”与“ abc”冲突时,即使我打算键入“ abcd”,我也无法在“ ab”之后键入“ c”。
我发现了有关edit: editting failed
问题 edit: editting failed
错误,似乎Qt.QueuedConnection
可以解决问题。 因此, tree.itemChanged
连接到重复检查功能,如果检查失败,它将提示用户再次输入名称。 可以选择弹出提示冲突的工具提示。
虽然可能不是理想的解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.