Remove a list of selected items in the QListView
Asked Answered
A

4

6

How can I remove a list of selected items in the QListView in QT 4.6. Something like this does not work, the iterator becomes invalid:

  QModelIndexList indexes = ui.listview_files->selectionModel()->selectedIndexes();
  foreach(QModelIndex index, indexes)
  {
    model->removeRow(index.row());
  }

removeRows also not suitable, it removes N-items that follows the one given. I use QStandardItemModel to store items.

Affaire answered 24/7, 2010 at 12:42 Comment(0)
I
9
QModelIndexList indexes;
while((indexes = ui.listview_files->selectionModel()->selectedIndexes()).size()) { 
    model->removeRow(indexes.first().row()); 
}
Illbehaved answered 24/7, 2010 at 12:53 Comment(2)
Oh, how simple it all) But not always remove. Here's the solution: QModelIndexList indexes = ui.listview_files->selectionModel()->selectedIndexes(); while(indexes.size()) { model->removeRow(indexes.first().row()); indexes = ui.listview_files->selectionModel()->selectedIndexes();Affaire
Edited to take your comment into account ;)Illbehaved
G
3

I don't know if it's a bug in new versions of Qt 4.8 but sje397 solution doesn't work for me (on a QTreeView).

I share the best solution i found which is to sort indexes in descending order and remove row from end to begin.

QModelIndexList indexes = pTreeview->selectionModel()->selectedIndexes();
qSort(indexes.begin(), indexes.end(), qGreater<QModelIndex>());

for(iter = indexes.constBegin(); iter != indexes.constEnd(); ++iter){
   pModels->removeRow((*iter).row(), (*iter).parent());
}
Goldeye answered 12/2, 2013 at 13:8 Comment(0)
S
2

Here I've excavated your question in 2016...

The problem with your original solution is that it invalidates indices, i.e. if you want to remove elements with indices 5, 6, and 7, after removing the fifth item, item number six now becomes item number five and so on.

To make your solution work, there's no need to evaluate selectionModel()->selectedIndexes() everytime in your loop. The trick is to start from the end and iterate back to the beginning. If you remove the item number 7 first, items with numbers 5 and 6 will keep their positions.

To give you folks some code:

QModelIndexList selectedIndexes(listView->selectionModel()->selectedIndexes());

for (QModelIndexList::const_iterator it = selectedIndexes.constEnd() - 1;
        it >= selectedIndexes.constBegin(); --it) {
    model->removeRow(it->row());
}

Hope this will help some random googler.

Savoury answered 30/5, 2016 at 9:42 Comment(1)
To make this work, you should sort the list before ascending. each Time you select, the item selected is pushed back to list. the list can be like this 1-9-5-4, then this solution won't work. selectedIndexes() This convenience function returns a list of all selected and non-hidden item indexes in the view. The list contains no duplicates, and is not sorted.Youngster
T
1

removing by multiple rows is more optimized:

QVector<QItemSelectionRange> ranges = ui.listView->selectionModel()->selection().toVector();
foreach (const QItemSelectionRange& range, ranges) {
    ui.listView->model()->removeRows(range.top(), range.height());
}
Toxin answered 23/1, 2018 at 11:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.