Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [SOLVED] QAbstractItemModel, row numers shifting during removing
QtWS25 Last Chance

[SOLVED] QAbstractItemModel, row numers shifting during removing

Scheduled Pinned Locked Moved General and Desktop
9 Posts 2 Posters 2.7k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    aliks-os
    wrote on last edited by aliks-os
    #1

    For example the following data structure

    rootNode
    |------Node1
    |------Node2
    |------Node3
    |------Node4
    |------Node5

    From 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?

    1 Reply Last reply
    0
    • M Offline
      M Offline
      mcosta
      wrote on last edited by
      #2

      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)

      Once your problem is solved don't forget to:

      • Mark the thread as SOLVED using the Topic Tool menu
      • Vote up the answer(s) that helped you to solve the issue

      You can embed images using (http://imgur.com/) or (http://postimage.org/)

      1 Reply Last reply
      0
      • A Offline
        A Offline
        aliks-os
        wrote on last edited by
        #3

        Hi...now shifting to another direction...
        Now deletes number 4 and 3

        1 Reply Last reply
        0
        • M Offline
          M Offline
          mcosta
          wrote on last edited by
          #4

          Hi,

          can you show your code??

          Once your problem is solved don't forget to:

          • Mark the thread as SOLVED using the Topic Tool menu
          • Vote up the answer(s) that helped you to solve the issue

          You can embed images using (http://imgur.com/) or (http://postimage.org/)

          1 Reply Last reply
          0
          • A Offline
            A Offline
            aliks-os
            wrote on last edited by aliks-os
            #5
            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());
            }
            
            1 Reply Last reply
            0
            • A Offline
              A Offline
              aliks-os
              wrote on last edited by aliks-os
              #6
              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();
              }
              
              1 Reply Last reply
              0
              • M Offline
                M Offline
                mcosta
                wrote on last edited by
                #7

                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.

                Once your problem is solved don't forget to:

                • Mark the thread as SOLVED using the Topic Tool menu
                • Vote up the answer(s) that helped you to solve the issue

                You can embed images using (http://imgur.com/) or (http://postimage.org/)

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  aliks-os
                  wrote on last edited by
                  #8

                  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?

                  1 Reply Last reply
                  0
                  • A Offline
                    A Offline
                    aliks-os
                    wrote on last edited by
                    #9

                    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();
                    }
                    
                    1 Reply Last reply
                    0

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved