[SOLVED] QAbstractItemModel, row numers shifting during removing
-
For example the following data structure
rootNode
|------Node1
|------Node2
|------Node3
|------Node4
|------Node5From the treeView, I try delete the Nodes 2 and 4.
<code>
QModelIndexList list = treeView->selectionModel()->selectedIndexes();
foreach(QModelIndex index, list) {
if (!index.isValid()) return;
treeview->model()->removeRows(index.row(), 1, index.parent());
}
</code>As a result I have that in facts the following Nodes are removed: 2 and 5.
As I understand after the first node removing, there is a shfting if row's numbers.How I can fixed it?
-
Hi,
my solution is to get the list of selected rows, sort it in decreasing order, and remove in that order.
For instance if you select rows (3, 1, 5) remove in order (5, 3, 1) -
Hi...now shifting to another direction...
Now deletes number 4 and 3 -
Hi,
can you show your code??
-
bool decSort(const QModelIndex &idx1, const QModelIndex &idx2) { return idx1.row() > idx2.row(); } //IN the TreeView QModelIndexList list = this->selectionModel()->selectedIndexes(); if (list.size() == 0) return; qSort(list.begin(), list.end(), decSort); foreach(QModelIndex index, list) { if (!index.isValid()) return; this->model()->removeRows(index.row(), 1, index.parent()); }
-
bool TreeModel::removeRows(int row, int count, const QModelIndex &parent) { TreeItem *parentItem; qDebug() << "REMOVE_ROWS"; if (!parent.isValid()) parentItem = rootItem; else parentItem = static_cast<TreeItem*>(parent.internalPointer()); if (row < 0 || row > parentItem->childCount()) { return false; } beginRemoveRows(parent, row, row + count - 1); for (int i=0; i < count; ++i) { if (!parentItem->removeChild(row)) break; } endRemoveRows(); }
-
Hi,
my idea is
QList <int> rows; QModelIndexList list = this->selectionModel()->selectedIndexes(); for (const QModelIndex &idx: list) rows << idx.row(); qSort(rows.begin(): rows.end(), qGreather<int>()); for (int i: rows) this->model()->removeRows(i, 1);
NOTE: This works only if, as you wrote in the first post, you have only top level items.
-
Yes, but I may to have not only top level items. Now I going to check another idea like as
QModelIndexList list = this->selectionModel()->selectedIndexes(); if (list.size() == 0) return; QList<TreeItem*> itmList; foreach(QModelIndex index, list) { if (!index.isValid()) return; TreeItem *item = static_cast<TreeItem*>(index.internalPointer()); itmList << item; } foreach(Item *item, itemList) { QModelIndex idx = model()->indexByItem(item); model()->removeRow(idx.row(), idx.parent()); }
then I am going write a function of searching indexByItem and use like above. What do you think?
-
So, the result is following
void QxTreeView::deleteSelected(bool value) { QModelIndexList list = this->selectionModel()->selectedIndexes(); if (list.size() == 0) return; QList<TreeItem*> itmList; foreach(QModelIndex index, list) { if (!index.isValid()) return; TreeItem *item = static_cast<TreeItem*>(index.internalPointer()); itmList << item; } TreeModel *model = static_cast<TreeModel*>(this->model()); foreach(TreeItem *item, itmList) { QModelIndex idxParent = this->rootIndex(); QModelIndex idx = model->indexByItem(idxParent, item); model->removeRow(idx.row(), idx.parent()); } }
and indexByItem
QModelIndex TreeModel::indexByItem(const QModelIndex &parent, TreeItem *item) { if (item == 0) return QModelIndex(); int row = 0; while (row < rowCount(parent)) { QModelIndex thisIndex = this->index(row, 0, parent); TreeItem *thisItem = static_cast<TreeItem*>(thisIndex.internalPointer()); if (thisItem == item) return thisIndex; if (thisItem->childCount() > 0) { thisIndex = indexByItem(thisIndex, item); if (thisIndex.isValid()) return thisIndex; } ++row; } return QModelIndex(); }