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. QTreeView selecting items programatically issue
Forum Updated to NodeBB v4.3 + New Features

QTreeView selecting items programatically issue

Scheduled Pinned Locked Moved Solved General and Desktop
6 Posts 3 Posters 2.0k 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
    Dariusz
    wrote on 28 Feb 2018, 00:55 last edited by Dariusz
    #1

    Hey

    I'm trying to create undo/redo command system but oh boy getting the selection to work is a headache.

    in my undo I store a list of column 0 elements of all selected items as nodes - no modelIndexes as they get messed up once I do drag/drop.

    The idea was store as items > retrieve their indexes during undo/redo & select them again. But for some reason I cant get it to work.

    Here is how I gather the items:

    void myView::mouseReleaseEvent(QMouseEvent *event) {
        dragActive = false;
        QTreeView::mouseReleaseEvent(event);
        //_newSelection = selectionModel()->selection(); //// Cant use QModelIndex, affter drag/drop/etc they all go bad.
        _newSelectionX = selectedIndexes();
    
        //if (_newSelectionX != _oldSelectionX) {
        std::vector<myNode *> _newSelectedNodes;
        for (int x = 0; x < _newSelectionX.size(); x += model()->columnCount()) { //// get only 1st item from 0 column, well use sibling later to create full selection from indexes.
            myNode *node = static_cast<myNode*>(_newSelectionX[x].internalPointer());
            _newSelectedNodes.emplace_back(node);
        }
        std::vector<myNode *> _oldSelectedNodes;
        for (int x = 0; x < _oldSelectionX.size(); x += model()->columnCount()) {
            myNode *node = static_cast<myNode*>(_oldSelectionX[x].internalPointer());
            _oldSelectedNodes.emplace_back(node);
        }
        selectionCommand::selectionData data;
        data._newSel = _newSelectedNodes;
        data._oldSel = _oldSelectedNodes;
        data._tree = this;
        emit selectionHasChanged(data);
    

    Here is how I undo/redo :

    void myView::changeMySelection(selectionCommand::selectionData data, bool undo) {
        clearSelection();
        int columnC = 1;//model()->columnCount() - 2;
        if (undo) {
            for (int x = 0; x < data._oldSel.size(); ++x) {
                QModelIndex itemIndex = data._oldSel[x]->index();
                QModelIndex siblingIndex = itemIndex.sibling(data._oldSel[x]->row(), columnC);
                qDebug() << itemIndex << siblingIndex;
                selectionModel()->select(QItemSelection(itemIndex, itemIndex), QItemSelectionModel::Select);
                //selectionModel()->select(QItemSelection(itemIndex, siblingIndex), QItemSelectionModel::Select);
            }
        } else {
            for (int x = 0; x < data._newSel.size(); ++x) {
                QModelIndex itemIndex = data._newSel[x]->index();
                QModelIndex siblingIndex = itemIndex.sibling(data._newSel[x]->row(), columnC);
                qDebug() << itemIndex << siblingIndex;
                selectionModel()->select(QItemSelection(itemIndex, itemIndex), QItemSelectionModel::Select);
    
            }
        }
    }
    

    Here is the log

    QModelIndex(16,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
    QModelIndex(2,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
    QModelIndex(1,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
    QModelIndex(0,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(0,1,0x15ac176b620,myModel(0x15ac06366f0))
    QModelIndex(1,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
    QModelIndex(2,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
    QModelIndex(2,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
    QModelIndex(0,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(0,1,0x15ac176b620,myModel(0x15ac06366f0))
    QModelIndex(2,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
    QModelIndex(2,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
    QModelIndex(1,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
    QModelIndex(0,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(0,1,0x15ac176b620,myModel(0x15ac06366f0))
    QModelIndex(1,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
    QModelIndex(2,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
    QModelIndex(16,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
    QModelIndex(15,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
    QModelIndex(13,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
    QModelIndex(15,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
    QModelIndex(16,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
    QModelIndex(2,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
    QModelIndex(1,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
    

    Only some of the selections actually undo/redo. I can not understand at all why on earth I'm getting wrong QModelIndexes. The left model index is valid, so right one next column should be valid as well. duhh !

    I even tried on selecting just 1 item (current example) and that only works in some cases. What am I doing wrong here ? :/

    R V 2 Replies Last reply 28 Feb 2018, 07:50
    0
    • D Dariusz
      28 Feb 2018, 00:55

      Hey

      I'm trying to create undo/redo command system but oh boy getting the selection to work is a headache.

      in my undo I store a list of column 0 elements of all selected items as nodes - no modelIndexes as they get messed up once I do drag/drop.

      The idea was store as items > retrieve their indexes during undo/redo & select them again. But for some reason I cant get it to work.

      Here is how I gather the items:

      void myView::mouseReleaseEvent(QMouseEvent *event) {
          dragActive = false;
          QTreeView::mouseReleaseEvent(event);
          //_newSelection = selectionModel()->selection(); //// Cant use QModelIndex, affter drag/drop/etc they all go bad.
          _newSelectionX = selectedIndexes();
      
          //if (_newSelectionX != _oldSelectionX) {
          std::vector<myNode *> _newSelectedNodes;
          for (int x = 0; x < _newSelectionX.size(); x += model()->columnCount()) { //// get only 1st item from 0 column, well use sibling later to create full selection from indexes.
              myNode *node = static_cast<myNode*>(_newSelectionX[x].internalPointer());
              _newSelectedNodes.emplace_back(node);
          }
          std::vector<myNode *> _oldSelectedNodes;
          for (int x = 0; x < _oldSelectionX.size(); x += model()->columnCount()) {
              myNode *node = static_cast<myNode*>(_oldSelectionX[x].internalPointer());
              _oldSelectedNodes.emplace_back(node);
          }
          selectionCommand::selectionData data;
          data._newSel = _newSelectedNodes;
          data._oldSel = _oldSelectedNodes;
          data._tree = this;
          emit selectionHasChanged(data);
      

      Here is how I undo/redo :

      void myView::changeMySelection(selectionCommand::selectionData data, bool undo) {
          clearSelection();
          int columnC = 1;//model()->columnCount() - 2;
          if (undo) {
              for (int x = 0; x < data._oldSel.size(); ++x) {
                  QModelIndex itemIndex = data._oldSel[x]->index();
                  QModelIndex siblingIndex = itemIndex.sibling(data._oldSel[x]->row(), columnC);
                  qDebug() << itemIndex << siblingIndex;
                  selectionModel()->select(QItemSelection(itemIndex, itemIndex), QItemSelectionModel::Select);
                  //selectionModel()->select(QItemSelection(itemIndex, siblingIndex), QItemSelectionModel::Select);
              }
          } else {
              for (int x = 0; x < data._newSel.size(); ++x) {
                  QModelIndex itemIndex = data._newSel[x]->index();
                  QModelIndex siblingIndex = itemIndex.sibling(data._newSel[x]->row(), columnC);
                  qDebug() << itemIndex << siblingIndex;
                  selectionModel()->select(QItemSelection(itemIndex, itemIndex), QItemSelectionModel::Select);
      
              }
          }
      }
      

      Here is the log

      QModelIndex(16,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
      QModelIndex(2,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
      QModelIndex(1,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
      QModelIndex(0,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(0,1,0x15ac176b620,myModel(0x15ac06366f0))
      QModelIndex(1,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
      QModelIndex(2,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
      QModelIndex(2,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
      QModelIndex(0,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(0,1,0x15ac176b620,myModel(0x15ac06366f0))
      QModelIndex(2,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
      QModelIndex(2,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
      QModelIndex(1,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
      QModelIndex(0,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(0,1,0x15ac176b620,myModel(0x15ac06366f0))
      QModelIndex(1,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
      QModelIndex(2,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
      QModelIndex(16,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
      QModelIndex(15,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
      QModelIndex(13,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
      QModelIndex(15,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
      QModelIndex(16,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
      QModelIndex(2,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
      QModelIndex(1,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
      

      Only some of the selections actually undo/redo. I can not understand at all why on earth I'm getting wrong QModelIndexes. The left model index is valid, so right one next column should be valid as well. duhh !

      I even tried on selecting just 1 item (current example) and that only works in some cases. What am I doing wrong here ? :/

      R Offline
      R Offline
      raven-worx
      Moderators
      wrote on 28 Feb 2018, 07:50 last edited by
      #2

      @Dariusz
      between the undo / redo command calls, does your model get updated (rows/columns added/removed)?

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      1 Reply Last reply
      0
      • D Offline
        D Offline
        Dariusz
        wrote on 28 Feb 2018, 08:22 last edited by
        #3

        Hey

        Nope, I'm only clicking on new rows. I have added my mouseReleaseEvent code in 1st post to show how I'm gathering the items.

        1 Reply Last reply
        0
        • D Dariusz
          28 Feb 2018, 00:55

          Hey

          I'm trying to create undo/redo command system but oh boy getting the selection to work is a headache.

          in my undo I store a list of column 0 elements of all selected items as nodes - no modelIndexes as they get messed up once I do drag/drop.

          The idea was store as items > retrieve their indexes during undo/redo & select them again. But for some reason I cant get it to work.

          Here is how I gather the items:

          void myView::mouseReleaseEvent(QMouseEvent *event) {
              dragActive = false;
              QTreeView::mouseReleaseEvent(event);
              //_newSelection = selectionModel()->selection(); //// Cant use QModelIndex, affter drag/drop/etc they all go bad.
              _newSelectionX = selectedIndexes();
          
              //if (_newSelectionX != _oldSelectionX) {
              std::vector<myNode *> _newSelectedNodes;
              for (int x = 0; x < _newSelectionX.size(); x += model()->columnCount()) { //// get only 1st item from 0 column, well use sibling later to create full selection from indexes.
                  myNode *node = static_cast<myNode*>(_newSelectionX[x].internalPointer());
                  _newSelectedNodes.emplace_back(node);
              }
              std::vector<myNode *> _oldSelectedNodes;
              for (int x = 0; x < _oldSelectionX.size(); x += model()->columnCount()) {
                  myNode *node = static_cast<myNode*>(_oldSelectionX[x].internalPointer());
                  _oldSelectedNodes.emplace_back(node);
              }
              selectionCommand::selectionData data;
              data._newSel = _newSelectedNodes;
              data._oldSel = _oldSelectedNodes;
              data._tree = this;
              emit selectionHasChanged(data);
          

          Here is how I undo/redo :

          void myView::changeMySelection(selectionCommand::selectionData data, bool undo) {
              clearSelection();
              int columnC = 1;//model()->columnCount() - 2;
              if (undo) {
                  for (int x = 0; x < data._oldSel.size(); ++x) {
                      QModelIndex itemIndex = data._oldSel[x]->index();
                      QModelIndex siblingIndex = itemIndex.sibling(data._oldSel[x]->row(), columnC);
                      qDebug() << itemIndex << siblingIndex;
                      selectionModel()->select(QItemSelection(itemIndex, itemIndex), QItemSelectionModel::Select);
                      //selectionModel()->select(QItemSelection(itemIndex, siblingIndex), QItemSelectionModel::Select);
                  }
              } else {
                  for (int x = 0; x < data._newSel.size(); ++x) {
                      QModelIndex itemIndex = data._newSel[x]->index();
                      QModelIndex siblingIndex = itemIndex.sibling(data._newSel[x]->row(), columnC);
                      qDebug() << itemIndex << siblingIndex;
                      selectionModel()->select(QItemSelection(itemIndex, itemIndex), QItemSelectionModel::Select);
          
                  }
              }
          }
          

          Here is the log

          QModelIndex(16,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
          QModelIndex(2,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
          QModelIndex(1,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
          QModelIndex(0,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(0,1,0x15ac176b620,myModel(0x15ac06366f0))
          QModelIndex(1,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
          QModelIndex(2,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
          QModelIndex(2,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
          QModelIndex(0,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(0,1,0x15ac176b620,myModel(0x15ac06366f0))
          QModelIndex(2,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
          QModelIndex(2,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
          QModelIndex(1,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
          QModelIndex(0,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(0,1,0x15ac176b620,myModel(0x15ac06366f0))
          QModelIndex(1,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
          QModelIndex(2,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
          QModelIndex(16,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
          QModelIndex(15,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
          QModelIndex(13,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
          QModelIndex(15,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
          QModelIndex(16,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
          QModelIndex(2,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
          QModelIndex(1,0,0x15ac176b620,myModel(0x15ac06366f0)) QModelIndex(-1,-1,0x0,QObject(0x0))
          

          Only some of the selections actually undo/redo. I can not understand at all why on earth I'm getting wrong QModelIndexes. The left model index is valid, so right one next column should be valid as well. duhh !

          I even tried on selecting just 1 item (current example) and that only works in some cases. What am I doing wrong here ? :/

          V Offline
          V Offline
          VRonin
          wrote on 28 Feb 2018, 08:35 last edited by
          #4

          @Dariusz said in QTreeView selecting items programatically issue:

          no modelIndexes as they get messed up once I do drag/drop

          QPersistentModelIndex should not get messed up unless the drag-drop implementation has a bug

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          1 Reply Last reply
          0
          • D Offline
            D Offline
            Dariusz
            wrote on 28 Feb 2018, 08:50 last edited by Dariusz
            #5

            Hey

            Yeah not sure to be honest. I dont use persistend model indexes, they are quite heavy from what I read and sicne I will have thousands of items. I though its more efficient to store pointer to items and then get their indexes from model. I tried storing before the QSelectionModel()->selection() and restoring that, it worked on QTreeWidget system, but on my QAbstractItemModel&treeView seems to be broken. I attached video with me dragging lots of stuff(https://goo.gl/zCiMhv), It seems to be working fine. I fire the before/after remove/add commands and so on. Its puzzling :- ( Over there I store pointers to items in an array>store that in my custom mimeData. The mimeData is used to carry the dragging of data as it should, and at the end of dropMimeData (before row removal/insertion) I store source item row/parent data/ to restore it later/ snipped below.

                    //// Drop mime data function
                    .... 
                    for (int i = count - 1; i >= 0; --i) {
                        if (nodes[i]->row() < row && parentNode == nodes[i]->parentNode())
                            --row;
                        // Remove from old position
            
                        moveCommand::moveData mData;
                        mData._node = nodes[i];
                        mData._source = sourceModel;
                        mData._destination = this;
                        mData._sourceRow = nodes[i]->row();
                        mData._destinationRow = row;
                        //mData._oldParentIndex = createIndex(nodes[i]->row(), 0, nodes[i]); /// obsolete - removed now after clean up - never used it
                        //mData._newParentIndex = parent; /// obsolete - removed now after clean up - never used it
                        mData._oldParent = nodes[i]->parentNode();
                        mData._newParent = parentNode;
                        moveData.push_back(mData);
            
                        sourceModel->removeNode(nodes[i]);
                        // Insert at new position
            
                        beginInsertRows(parent, row, row);
                        parentNode->insertChild(row, nodes[i]);
                        endInsertRows();
                        ++row;
                    }
                    emit treeModelItemMoved(moveData);
            

            Updated snipped a little.

            1 Reply Last reply
            0
            • D Offline
              D Offline
              Dariusz
              wrote on 28 Feb 2018, 09:10 last edited by Dariusz
              #6

              SOLVED!

              In QAbstractItemModel ::indexFromitem() I had wrong argument passed in createIndex(), I was passing item.parent() instead of item as third arg.. argh!!! Thanks for juggling my brain :- )

              The only thing I have to solve now is to re-select items properly after drop action. I wonder whats wrong humhhhh

              1 Reply Last reply
              0

              2/6

              28 Feb 2018, 07:50

              4 unread
              • Login

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