2015-11-19 1 views
1

J'ai un QListView qui contient plusieurs QStandardItems qui sont contenus dans un QStandardItemModel. Les éléments du modèle ont des cases à cocher activées. J'ai un QPushButton qui se connecte à la méthode suivante (qui appartient à une classe qui hérite de QTabWidget) lorsque vous cliquez dessus:Suppression de QStandardItems de QStandartItemModel dans QListView dans PyQt4 en utilisant une boucle

def remove_checked_files(self): 
    rows_to_remove = [] # will contain the row numbers of the rows to be removed. 
    for row in range(self.upload_list_model.rowCount()): # iterate through all rows. 
     item = self.upload_list_model.item(row) # get the item in row. 
     if item.checkState() == 2: # if the item is checked. 
      rows_to_remove.append(row) 
    for row in rows_to_remove: 
     # this loop SHOULD remove all the checked items, but only removes 
     # the first checked item in the QListView 
     self.upload_list_model.removeRow(row) 

Le problème est, comme je l'ai dit dans les commentaires de code, que seul le premier élément coché de la liste est supprimée. Je sais que le dernier pour boucles de boucle autant de fois que le nombre de cases cochées, donc removeRow est appelé le nombre correct de fois.

Comment puis-je résoudre ce problème?

Edit:

self.upload_list_model est le QStandardItemModel

Edit2:

Je me suis rendu compte que le problème réside dans la dernière boucle: il change les indices de ligne dans chaque boucle faisant la liste rows_to_remove inutile pour les prochaines déménagements. Donc j'ai eu tort quand j'ai dit que la boucle ne supprime qu'un élément du modèle, elle essaye toujours de supprimer la bonne quantité d'éléments, mais dans mes tests j'ai essayé d'enlever le second et le dernier élément (par exemple), et après En supprimant le second, le dernier élément n'était plus dans la rangée que la boucle essayait de retirer.

Maintenant, je comprends le problème, mais je ne sais toujours pas comment modifier les index de ligne tout au long de la boucle. Des suggestions pour cela?

+1

Essayez: 'pour la ligne en inversée (rows_to_remove):'. – ekhumoro

+0

@ekhumoro c'est très simple et efficace, merci. – Valence

Répondre

2

j'ai réussi à résoudre le problème avec cette méthode récursive:

def remove_checked_files(self): 

    for row in range(self.upload_list_model.rowCount()): 
     item = self.upload_list_model.item(row) # get the item in row. 
     if item and item.checkState() == 2: # if the item is checked. 
      self.upload_list_model.removeRow(row) 
      self.remove_checked_files()