如何从QTreeWidget、QListWidget或QListView中删除多个项目

0 投票
2 回答
1686 浏览
提问于 2025-04-18 16:09

我有一份 QTreeWidget 项目的索引列表:

indexesToDelete=[1, 3, 5 ,7]

现在如果我这样做:

for itemIndex in indexesToDelete:
    myTree.takeTopLevelItem(itemIndex) # deletes an item from Tree

事情就变得很麻烦了。在每次 for itemIndex in indexesToDelete 循环中,都会删除一个项目,而树形项目的索引在循环进行时也会发生变化……不用说,只有第一次的循环迭代能正确删除列表中的项目。其他的列表项目都被错误地删除了。

问题:如何才能正确地通过索引删除列表项目呢?

2 个回答

0

首先,我想说明的是,你实际上并不是通过 QModelIndex 来删除东西,而是通过一个整数,这个整数是你和特定项目(或者一组项目的行)关联起来的。如果你真的有每个想要删除的项目的 QModelIndex,你会发现,在第一次删除之后,当你查询 index.isValid() 时,所有的索引都会返回 False。这很容易理解,显然,当你删除一个项目时,所有的索引都会变得无效(正如你发现的那样)。

简而言之,Qt 的设计就是为了防止你做你现在尝试做的事情!

唯一可靠的解决方案是根据项目列表来删除。如果你想的话,可以在每次删除循环中查找项目的索引(然后通过索引删除),但你不能存储一个索引列表并期待删除能正常工作。

2

一个想法是通过具体的项目来删除,而不是不断地改变索引号。首先,先建立一个要删除的项目列表。然后在树形结构中遍历这些项目,把每个项目和要删除的列表中的项目进行比较。如果相同,就删除。

QListWidget()

myListWidget=QtGui.QListWidget()

for i in range(10):
    item=QtGui.QtGui.QListWidgetItem()
    myListWidget.addItem(item)

indexToRemove=[2,4,6]

itemsToRemove=[]
for index in indexToRemove:
    item=myListWidget.item(index)
    if item: itemsToRemove.append(item)

for i in range(myListWidget.count()):
    listItem = myListWidget.item(i)
    if not listItem: continue
    if not listItem in itemsToRemove: continue                  
    itemRow=myListWidget.row(listItem)
    if itemRow:
        myListWidget.takeItem(itemRow)

QTreeWidget()

myTreeWidget=QtGui.QTreeWidget()

for i in range(10):
    item=QtGui.QtGui.QTreeWidgetItem()
    myTreeWidget.addTopLevelItem(item)

indexToRemove=[2,4,6]

itemsToRemove=[]
for index in indexToRemove:
    item=myTreeWidget.topLevelItem(index)
    if item: itemsToRemove.append(item)

for i in range(myTreeWidget.topLevelItemCount()):
    listItem=myTreeWidget.topLevelItem(i)
    if not listItem: continue
    if not listItem in itemsToRemove: continue
    itemIndex=myTreeWidget.indexOfTopLevelItem(listItem)
    if not itemIndex: continue             
    myTreeWidget.takeTopLevelItem(itemIndex)

撰写回答