我正在使用PyQt4和Python3构建一个应用程序,该应用程序使用QTreeWidget为用户提供了一种方法,可以在将数据加载到应用程序后选择他们想要与之交互的数据部分。
树通常有3个级别。我将它们称为祖父母(文件夹),父(标题)和子(扫描)。
作为其中的一部分,我已经包含一个按钮,只需清除所有复选框(即将它们全部设置为未选中)。但是,当我这样做时,我会遇到一些奇怪的行为。解释:
第二次观察发生的方式并不一致。有时,例如,对于父和祖父母来说,从部分检查到未检查的转换都会挂起。其他时候,祖父母将立即改变,但父母将挂起,几秒钟后改变。
与上面类似,如果检查了其中一个父项(因此,部分检查了祖父母,完全检查了父项的所有子项),尝试清除所有复选框会导致所有父项和子项复选框都转换立即,但祖父母复选框挂起一段时间后,从部分检查转为未选中。
会产生问题的简化代码:
class MyTree(QtGui.QWidget):
def __init__(self):
super().__init__()
layout = QtGui.QVBoxLayout(self)
self.tree = QtGui.QTreeWidget()
clear_btn = QtGui.QPushButton("Clear Checkboxes")
clear_btn.clicked.connect(self.clear_checked)
self.update_tree()
layout.addWidget(self.tree)
layout.addWidget(clear_btn)
def update_tree(self):
folders = {'folder1': {'signal1': ['Sweep1', 'Sweep2'], 'signal2': ['Sweep1', 'Sweep2']},
'folder2': {'signal1': ['Sweep1', 'Sweep2'], 'signal2': ['Sweep1', 'Sweep2']}}
for folder, headers in sorted(folders.items()):
grandparent_item = QtGui.QTreeWidgetItem(self.tree)
grandparent_item.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsTristate | QtCore.Qt.ItemIsUserCheckable)
grandparent_item.setText(0, folder)
for header, sweeps in sorted(headers.items()):
parent_item = QtGui.QTreeWidgetItem(grandparent_item)
parent_item.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsTristate | QtCore.Qt.ItemIsUserCheckable)
parent_item.setCheckState(0, QtCore.Qt.Unchecked)
parent_item.setText(0, header)
for sweep in sweeps:
child_item = QtGui.QTreeWidgetItem(parent_item)
child_item.setCheckState(0, QtCore.Qt.Unchecked)
child_item.setText(0, sweep)
def clear_checked(self):
root = self.tree.invisibleRootItem()
folder_count = root.childCount()
for i in range(folder_count):
folder = root.child(i)
folder.setCheckState(0, QtCore.Qt.Unchecked)
所以,测试将是:
不确定如何解决这个问题,所以任何建议都会受到赞赏。
编辑1:
所以只是玩这个,我注意到会发生的事情是,在移动鼠标之前,不会发生从部分检查到检查祖父母和/或父级的转换(取决于检查整个树中的内容) 。如果我点击“清除复选框”按钮,只要我不移动鼠标,部分选中的框将保持部分检查。但是,一旦我移动鼠标,它们就会正常转换。