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. Move qtreeview rows
Forum Updated to NodeBB v4.3 + New Features

Move qtreeview rows

Scheduled Pinned Locked Moved General and Desktop
5 Posts 4 Posters 6.1k Views 1 Watching
  • 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.
  • D Offline
    D Offline
    DBGTMaster
    wrote on last edited by
    #1

    Hello,

    I have a qtreeview with a qstandarditemmodel..

    I would move a row with all subentries to a new position.

    I tried:
    @ moveRow( customerItem->parent()->index(), customerItem->row(),
    _customerGroupsToItems[groupId]->index(), 0);@

    And now, i readed in the documentation auf moveRows:
    @The base class implementation does nothing and returns false.@

    How can i solve my issue?

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      This is because QStandardItemModel doesn't know anything about your underlying data so it can't move things around for you.

      You have to implement moveRows for your model if you want to use moveRow.

      Hope it helps

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • D Offline
        D Offline
        David Stiel
        wrote on last edited by
        #3

        Hi,
        I had the same problem moving a row within a flat QStandardItemModel. It took some figuring out to get the move operation working properly with eg. QML ListView. I ended up doing:

        @void MyModel::move(int from, int to, int)
        {
        ... //range checking etc.

        int toSignal = to;
        if(from < to){
            toSignal += 1;
        }
        
        if(!beginMoveRows(QModelIndex(), from, from, QModelIndex(), toSignal)){
            return;
        }
        blockSignals(true);
        QStandardItem* fromItem = takeItem(from);
        removeRow(from);
        insertRow(to, fromItem);
        blockSignals(false);
        endMoveRows();
        

        }@

        DiracsbracketD 1 Reply Last reply
        1
        • D David Stiel

          Hi,
          I had the same problem moving a row within a flat QStandardItemModel. It took some figuring out to get the move operation working properly with eg. QML ListView. I ended up doing:

          @void MyModel::move(int from, int to, int)
          {
          ... //range checking etc.

          int toSignal = to;
          if(from < to){
              toSignal += 1;
          }
          
          if(!beginMoveRows(QModelIndex(), from, from, QModelIndex(), toSignal)){
              return;
          }
          blockSignals(true);
          QStandardItem* fromItem = takeItem(from);
          removeRow(from);
          insertRow(to, fromItem);
          blockSignals(false);
          endMoveRows();
          

          }@

          DiracsbracketD Offline
          DiracsbracketD Offline
          Diracsbracket
          wrote on last edited by Diracsbracket
          #4

          @David-Stiel
          Thanks!
          I adapted your example to work with a QTreeView with more than 1 column, as follows (only 1 step up/down per invocation)

          bool StandardItemModel::move(int from, bool isUp)
          {
              //range checking etc.
              const int numRows = rowCount();
          
              if (from<0 || from>=numRows || (from==0 && isUp) || (from==numRows-1 && !isUp))
                  return false;
          
              const int to = isUp ? from - 1: from + 1;
          
              //See documentation
              //http://doc.qt.io/qt-5/qabstractitemmodel.html#beginMoveRows
              //on why this is needed?
              const int toSignal = isUp ? to : to + 1;
          
              if (!beginMoveRows(QModelIndex(), from, from, QModelIndex(), toSignal))
                  return false;
          
              blockSignals(true);
              QList<QStandardItem*> fromRow = takeRow(from); //this also removes it from the model!
              insertRow(to, fromRow); //but the actual insertion must be done using to, not toSignal!
              blockSignals(false);
          
              endMoveRows();
          
              return true;
          }
          

          Note that there is no removeRow(from) in the adapted code, as takeRow(from) seems to already take care of that.
          In a dialog, I have Move Up and Move Down buttons that call the following dialog method:

          void changeOrderDialog::moveCurrentRow(bool isUp)
          {
              const QModelIndex index = ui->treeView->currentIndex();
          
              if (index.isValid())
              {
                  StandardItemModel* model = qobject_cast<StandardItemModel*>(ui->treeView->model());
                  const int row = index.row();
          
                  if (model->move(row, isUp))
                  {
                      const QModelIndex newIndex = model->index(isUp ? row-1 : row+1, 0);
                      ui->treeView->setCurrentIndex(newIndex);
                  }
              }
          }
          
          DiracsbracketD 1 Reply Last reply
          1
          • DiracsbracketD Diracsbracket

            @David-Stiel
            Thanks!
            I adapted your example to work with a QTreeView with more than 1 column, as follows (only 1 step up/down per invocation)

            bool StandardItemModel::move(int from, bool isUp)
            {
                //range checking etc.
                const int numRows = rowCount();
            
                if (from<0 || from>=numRows || (from==0 && isUp) || (from==numRows-1 && !isUp))
                    return false;
            
                const int to = isUp ? from - 1: from + 1;
            
                //See documentation
                //http://doc.qt.io/qt-5/qabstractitemmodel.html#beginMoveRows
                //on why this is needed?
                const int toSignal = isUp ? to : to + 1;
            
                if (!beginMoveRows(QModelIndex(), from, from, QModelIndex(), toSignal))
                    return false;
            
                blockSignals(true);
                QList<QStandardItem*> fromRow = takeRow(from); //this also removes it from the model!
                insertRow(to, fromRow); //but the actual insertion must be done using to, not toSignal!
                blockSignals(false);
            
                endMoveRows();
            
                return true;
            }
            

            Note that there is no removeRow(from) in the adapted code, as takeRow(from) seems to already take care of that.
            In a dialog, I have Move Up and Move Down buttons that call the following dialog method:

            void changeOrderDialog::moveCurrentRow(bool isUp)
            {
                const QModelIndex index = ui->treeView->currentIndex();
            
                if (index.isValid())
                {
                    StandardItemModel* model = qobject_cast<StandardItemModel*>(ui->treeView->model());
                    const int row = index.row();
            
                    if (model->move(row, isUp))
                    {
                        const QModelIndex newIndex = model->index(isUp ? row-1 : row+1, 0);
                        ui->treeView->setCurrentIndex(newIndex);
                    }
                }
            }
            
            DiracsbracketD Offline
            DiracsbracketD Offline
            Diracsbracket
            wrote on last edited by Diracsbracket
            #5

            @Diracsbracket
            Although this seems to work correctly in the QTreeView, I get the error messages in the Debugger as explained in this post.
            https://forum.qt.io/topic/86021/qabstractitemmodel-endmoverows-invalid-index

            Update: The problem I mentioned in that post was solved by @proman. I should have taken the time to read Qt's online Model/View Programming documentation, as it is clearly mentioned there...

            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