我有一个
QTreeWidget
项目索引列表:
indexesToDelete=[1, 3, 5 ,7]
现在如果我这样做:
for itemIndex in indexesToDelete:
myTree.takeTopLevelItem(itemIndex) # deletes an item from Tree
事情变得非常糟糕。每次
for itemIndex in indexesToDelete
迭代都会删除一个项目,并且即使 for
循环仍在进行,树项目的索引也会发生变化......不用说,只有第一个 for 循环迭代才会删除正确的列表项目。所有其他列表项均被不正确地删除。
问题:如何正确按索引删除列表项?
一个想法是按项目删除,而不是不断更改索引号。 首先建立要删除的项目列表。然后迭代 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)
所以我想首先指出,您实际上并不是通过
QModelIndex
删除的,而是通过与特定项目(或项目行)关联的整数来删除的。如果您实际上对要删除的每个项目都有 QModelIndex
,您会发现在第一次删除后,当您查询 False
时,所有索引都会返回 index.isValid()
。这应该很有意义,显然当您删除一个项目时,所有索引都会变得无效(正如您所发现的)。
简而言之,Qt 应该帮助您阻止您尝试做的事情!
唯一可靠的解决方案是根据项目列表进行删除。如果需要,您可以在删除循环的每次迭代中从项目中查找项目索引(并按索引删除),但您无法存储索引列表并期望删除能够正常工作。
选项 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)