Search code examples
pythonpyqt

How to delete multiple Items from QTreeWidget, QListWidget or QListView


I have a list of QTreeWidget items indexes:

indexesToDelete=[1, 3, 5 ,7]

Now if I do:

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

the things get really nasty. With every for itemIndex in indexesToDelete iteration an Item deleted and Tree Item's indexes are changed even while for loop is still going... Needless to say that only the very first for loop iteration deletes a correct List Item. All other list items are removed improperly.

Question: How to delete List Items by their indexes correctly?


Solution

  • An idea is to remove by item instead of constantly changing index numbers. First build a list of items to be removed. Then iterate the items in a Tree comparing each against the ones stored in a items-to-be-removed list . Delete if True.

    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)