【问题标题】:How to delete all topLevel QTreeWidgetItems and secondLevel QTreeWidgetItems without children?如何删除所有没有子级的顶级 QTreeWidgetItems 和二级 QTreeWidgetItems?
【发布时间】:2021-09-23 04:41:03
【问题描述】:

我在 Python 3.9.6 上使用 PyQt6。

我有一个三级 QTreeWidget,这意味着所有顶级项目都有孩子,顶级项目的孩子也有孩子,顶级项目的孙子没有孩子。

它的结构是这样的:

Tree                level 0
    Artist          level 1
        Album       level 2
            Song    level 3

我有一些删除歌曲节点的代码,也就是3级节点,只有3级节点会被直接删除。

很明显,当一个专辑的所有歌曲都被删除时,专辑将是空的,我想删除所有空的专辑,这链接到链中的另一个动作:当一个艺术家的所有专辑都被删除时,艺术家也应该被删除。

所以这变成:删除所有没有子级的二级项目,然后删除所有没有子级的一级项目。

这是我尝试过的,显然它不起作用也不应该起作用:

count = tree.topLevelItemCount()
for i in range(count):
    node = tree.topLevelItem(i)
    num = node.childCount()
    for j in range(num):
        child = node.child(j)
        if child.childCount() == 0:
            sip.delete(child)
    if node.childCount() == 0:
        sip.delete(node)

因为当项目被删除时,索引会改变,所以一个简单的for循环不应该起作用。

而且我不能使用 while 循环,因为我不想清空所有内容,所以我不知道如何在这里使用 while 循环而不让它永远运行。

那该怎么做呢?

【问题讨论】:

    标签: python python-3.x pyqt pyqt6


    【解决方案1】:

    我已经想通了,我只需要在删除之前使用列表推导获取所有顶级项目,然后使用第一个循环的结果使用另一个列表推导获取第二级项目。

    然后直接循环第二个推导的结果,不使用索引,因为for循环是单向的,并且当前项之后的项目保证存在于树中,直接删除它们而不是索引应该没问题。

    然后循环遍历第一个推导的结果,直接删除项目。

    代码:

    count = tree.topLevelItemCount()
    nodes = [tree.topLevelItem(i) for i in range(count)]
    children = [node.child(j) for node in nodes for j in range(node.childCount())]
    for child in children:
        if child.childCount() == 0:
            sip.delete(child)
    for node in nodes:
        if node.childCount() == 0:
            sip.delete(node)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-30
      • 1970-01-01
      • 2011-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-17
      相关资源
      最近更新 更多