我在 Python 3.9.6 上使用 PyQt6。
我有一个看起来像这样的三层 QTreeWidget:
A0
A1
a2
b2
B1
c2
d2
B0
C1
e2
其中,每个顶级项和二级项都保证有子项,除非三级项被删除,并且三级项永远不会有子项。
我有一个修改填充树的数据的函数,它可以重命名显示的字段,我希望树反映对数据的更改并合并父级。
QTreeWidgetItems的标识如下:
tree.topLevelItem(a).child(b).child(c)
其中a
和是自然数。b
c
给定 QTreeWidgetItem 的字段,我有一种方法可以确定任何项目的索引。
例如,如果树包含上述数据,输入[A0]
和函数返回[0]
,并且:
[A0, A1] -> [0, 0]
[A0, A1, a2] -> [0, 0, 0]
[A0, A1, b2] -> [0, 0, 1]
数据对应三级项,每个三级项对应一个列表,父项存在是为了对项进行分组。
例如,将生成上述树的数据:
[[A0, A1, a2],
[A0, A1, b2],
[A0, B1, c2],
[A0, B1, d2],
[B0, C1, e2]]
变量都是字符串。
现在,如果我想替换 A1 的所有实例,其中 A1 位于索引 1 并且索引 0 处的元素是 A0,我希望树看起来像这样:
A0
B1
a2
b2
c2
d2
B0
C1
e2
然后,如果我用 B0 替换索引 0 处所有出现的 A0,树应该如下所示:
B0
B1
a2
b2
c2
d2
C1
e2
我的想法是使用tree.topLevelItem(a).child(b)
获取需要删除的项目,然后使用[item.child(i) for i in range(item.childCount())]
获取第三级项目(如果结果列表的元素有孩子,则重复列表组合一次),然后进行一些操作以进行修改数据,然后创建节点并.addChild()
在需要修改的项目上使用,最后sip.delete()
在需要删除的项目上使用。
本质上,要实现上述两个步骤,代码基本上做了以下工作:
item = tree.topLevelItem(0).child(0)
children = [item.child(i) for i in range(item.childCount())]
for child in children:
data = child.info
data[1] = B1
node = TreeNode(data)
tree.topLevelItem(0).child(1).addChild(node)
sip.delete(item)
item = tree.topLevelItem(0)
children = [item.child(i) for i in range(item.childCount())]
children = [child.child(i) for child in children for i in range(child.childCount())]
for child in children:
data = child.info
data[0] = B0
node = TreeNode(data)
items = [tree.topLevelItem(1).child(i) for i in range(tree.topLevelItem(1).childCount())]
parent = None
for it in items:
if it.info[1] == data[1]:
parent = it
break
if not parent:
parent = TreeNode([B0, data[1]])
tree.topLevelItem(1).addChild(parent)
parent.addChild(node)
sip.delete(item)
当然,代码是不完整的,没有功能的,它不包括条件语句和类定义等,那是因为我试图让我的例子尽可能地小,尽管你确实明白我的代码背后的想法.
我想知道,什么是更优雅和更有效的解决方案来实现相同的结果,我已经谷歌搜索了几天,但又找不到任何有用的东西,这就是我在这里问的原因。