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

问题描述 投票:0回答:3

我有一个

QTreeWidget
项目索引列表:

indexesToDelete=[1, 3, 5 ,7]

现在如果我这样做:

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

事情变得非常糟糕。每次

for itemIndex in indexesToDelete
迭代都会删除一个项目,并且即使
for
循环仍在进行,树项目的索引也会发生变化......不用说,只有第一个 for 循环迭代才会删除正确的列表项目。所有其他列表项均被不正确地删除。

问题:如何正确按索引删除列表项?

python pyqt
3个回答
2
投票

一个想法是按项目删除,而不是不断更改索引号。 首先建立要删除的项目列表。然后迭代 Tree 中的项目,将每个项目与要删除的项目列表中存储的项目进行比较。如果为真则删除。

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)

0
投票

所以我想首先指出,您实际上并不是通过

QModelIndex
删除的,而是通过与特定项目(或项目行)关联的整数来删除的。如果您实际上对要删除的每个项目都有
QModelIndex
,您会发现在第一次删除后,当您查询
False
时,所有索引都会返回
index.isValid()
。这应该很有意义,显然当您删除一个项目时,所有索引都会变得无效(正如您所发现的)。

简而言之,Qt 应该帮助您阻止您尝试做的事情!

唯一可靠的解决方案是根据项目列表进行删除。如果需要,您可以在删除循环的每次迭代中从项目中查找项目索引(并按索引删除),但您无法存储索引列表并期望删除能够正常工作。


0
投票

选项 1:创建项目列表,然后循环遍历行

基于@alphanumeric的答案,但有一个小错误修复:

list_widget = QListWidget()

for i in range(10):
    list_item = QStandardItem(f"Item {i}")
    list_item.setData(i)
    list_widget.addItem(list_item)

indexes_to_remove = [2,3,4,6] # the previous solution wouldn't remove row 3

items_to_remove = []
for index in indexes_to_remove:
    item = list_widget.item(index)
    if item:
        items_to_remove.append(item)

# important: create list of items outside of loop to avoid skipping over remove items
list_items = [
    list_widget.item(i)
    for i in range(list_widget.count())
]

for list_item in list_items:
    list_item = list_widget.item(i)
    if not list_item: continue
    if not list_item in items_to_remove: continue                  
    item_row = list_widget.row(list_item)
    if list_row:
        list_widget.takeItem(item_row)

选项 2:对行列表进行反向排序 在删除之前只需颠倒要删除的行列表的顺序即可:

list_widget = QListWidget()

for i in range(10):
    list_item = QStandardItem(f"Item {i}")
    list_item.setData(i)
    list_widget.addItem(list_item)

indexes_to_remove = [2,3,4,6] # the previous solution wouldn't remove row 3

for row in sorted(indexes_to_remove, reverse=True):
    list_widget.removeRow(row)
© www.soinside.com 2019 - 2024. All rights reserved.