我正在使用 PyQt4 和 Python3 构建一个应用程序,该应用程序使用 QTreeWidget 为用户提供一种方法来选择他们希望在将其加载到应用程序后与之交互的数据部分。
这棵树通常有 3 个级别。我将它们称为祖父母(文件夹)、父母(标题)和孩子(扫描)。
作为其中的一部分,我添加了一个按钮来简单地清除所有复选框(即将它们全部设置为未选中)。但是,当我这样做时,我会遇到一些奇怪的行为。解释:
- 如果完全检查祖父母(即未部分检查),则清除工作正常
- 但是,例如,如果只有一个孩子被选中(意味着父母和祖父母都被部分选中),则将父母和祖父母设置为未选中会有延迟(我只看复选框何时从部分选中到未选中)。子项立即从选中变为未选中,但其他更改有几秒钟的延迟。
这第二个观察在它发生的方式上并不一致。有时,例如,从部分检查到未检查的父级和祖父级的转换都挂起。其他时候,祖父母会立即改变,但父母会挂起,几秒钟后改变。
与上面类似,如果选中了其中一个 Parent 项目(因此,Grandparent 部分选中,Parent 的所有子项都被完全选中),尝试清除所有复选框会导致所有 Parent 和 Child 复选框立即转换,但是祖父母复选框在从部分选中过渡到未选中之前挂起一段时间。
将产生问题的简化代码:
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”并尝试“清除复选框” - 这应该可以正常工作
- 检查“folder1”下“signal1”下的“Sweep1”并尝试“Clear checkboxes” - 这应该会产生上述问题
- 检查“文件夹1”下的“信号1”并尝试“清除复选框” - 这应该会产生上述问题
不知道如何解决这个问题,所以任何建议都将不胜感激。
编辑1:
所以只是玩这个,我注意到发生的事情是从部分检查到检查祖父母和/或父母(取决于整个树中检查的内容)的转换在鼠标移动之前不会发生。如果我点击“清除复选框”按钮,只要我不移动鼠标,部分选中的框将保持部分选中状态。但是,一旦我移动鼠标,它们就会正确过渡。