Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Solved QAbstractItemModel::endMoveRows: Invalid index

    General and Desktop
    2
    4
    2280
    Loading More Posts
    • 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.
    • Diracsbracket
      Diracsbracket last edited by Diracsbracket

      Hi,
      To move a row of a QTreeView up or down with a button click, I have adapted the code from here to this code, which I reproduce here for convenience:

      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);
              }
          }
      }
      

      Although the moves up and down + boundary conditions seem to work correctly, I get the following debugger messages (one triplet per up/down move, probably because I have 3 columns per row):

      //Error on the moveUp (to lower row index):
      QAbstractItemModel::endMoveRows:  Invalid index ( -2 , -1 ) in model StandardItemModel(0x779ad90)
      QAbstractItemModel::endMoveRows:  Invalid index ( -2 , -1 ) in model StandardItemModel(0x779ad90)
      QAbstractItemModel::endMoveRows:  Invalid index ( -2 , -1 ) in model StandardItemModel(0x779ad90)
      
      //Error on the moveDown (to higher row index):
      QAbstractItemModel::endMoveRows:  Invalid index ( 0 , -1 ) in model StandardItemModel(0x779ad90)
      QAbstractItemModel::endMoveRows:  Invalid index ( 0 , -1 ) in model StandardItemModel(0x779ad90)
      QAbstractItemModel::endMoveRows:  Invalid index ( 0 , -1 ) in model StandardItemModel(0x779ad90)
      

      What do I need to do to avoid these messages?

      P 1 Reply Last reply Reply Quote 0
      • P
        proman @Diracsbracket last edited by

        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!
        
        //add this 
        beginInsertRows(QModelIndex(),from,toSignal);
        
        insertRow(to, fromRow); //but the actual insertion must be done using to, not toSignal!
        blockSignals(false);
        
        endMoveRows();
        
        return true;
        

        }

        it`s work for me.

        Diracsbracket 1 Reply Last reply Reply Quote 0
        • Diracsbracket
          Diracsbracket @proman last edited by

          @proman said in QAbstractItemModel::endMoveRows: Invalid index:

          //add this
          beginInsertRows(QModelIndex(),from,toSignal);

          @proman, many thanks for your reply, and apologies for this late reaction. I did not recall seeing a notification about your post in my Qt notifications list and just happened to stumble on this old post of mine by accident.

          Your addition works, I no longer have the debugger messages. Thanks again!

          1 Reply Last reply Reply Quote 0
          • Diracsbracket
            Diracsbracket last edited by Diracsbracket

            The problem I mentioned in my post above and in the reference therein to another post of mine was solved graciously by @proman.

            He mentioned that I should add

            beginInsertRows(QModelIndex(),from,toSignal); 
            

            before doing

            insertRow(to, fromRow);  
            

            This avoids the debugger error messages.

            UPDATE:
            then line should actually be:

            beginInsertRows(QModelIndex(),toSignal,toSignal); 
            

            otherwise, you'll get ASSERT error messages when moving up because last<first.

            1 Reply Last reply Reply Quote 1
            • First post
              Last post