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. Receiving notification on internal movement of items inside a QTreeWidget

Receiving notification on internal movement of items inside a QTreeWidget

Scheduled Pinned Locked Moved General and Desktop
7 Posts 2 Posters 4.7k 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.
  • N Offline
    N Offline
    neuviemep
    wrote on last edited by
    #1

    I subclassed QTreeWidget and set dragDropMode to InternalMove. Moving items inside the tree works as expected, but I need to react to the items changing their order. Unfortunately, there's no signal that I could connect to that would let me do that.

    I obtained the handle to the underlying model via QTreeWidget::model() and connected to the model's rowsMoved() signal, but unfortunately, it doesn't seem to be emitted for internal moves.

    I also tried reimplementing dropEvent(), but I can't find a way to reliably obtain the destination row index there. From event->pos() I can obtain a QModelIndex of the item under the cursor, but this is useless, because while the drop indicator stays in place between two items, I get the index of the one above if I move the mouse a pixel up, and the one below if I move it down - even though the destination of the move is the same.

    How can I receive notifications of item moves and react to them?

    1 Reply Last reply
    0
    • B Offline
      B Offline
      Buckets
      wrote on last edited by
      #2

      I take it you are dynamically changing the order of the QTreeWidget when given certain data, or sorting.

      When you reimplemented the dropEvent() are you emitting a signal? If there isn't a signal you like you can always make your own.

      i'm not sure if this will help you at all: http://qt-project.org/wiki/Qt_for_beginners_Signals_and_slots_2

      ba ba ba
      ba na na na

      1 Reply Last reply
      0
      • N Offline
        N Offline
        neuviemep
        wrote on last edited by
        #3

        The problem is not that I don't know how to emit my own signals, but that I have trouble finding out which item(s) moved exactly where.

        The way I see it, since QTreeWidget has signals like itemClicked(), itemChanged() etc., it should also have itemMoved(from, to) which would let me react to the move easily.

        1 Reply Last reply
        0
        • N Offline
          N Offline
          neuviemep
          wrote on last edited by
          #4

          I figured it out:

          @
          void ProjectTree::dropEvent(QDropEvent *event)
          {
          // retrieve the target of the drop
          QTreeWidgetItem *target = itemAt(event->pos());
          DropIndicatorPosition dropPos = dropIndicatorPosition();
          // when the drop indicator points above an item, then this is the
          // correct one, otherwise, replace target item with the one below
          if (dropPos == BelowItem) target = itemBelow(target);

          // get list of selected items from the tree; these are the dragged
          // items
          QList<QTreeWidgetItem*> dragItems = selectedItems();

          // default implementation takes care of the actual move
          QTreeWidget::dropEvent(event);
          // notify subscribers of item move in some user-friendly way
          emit itemsMoved(...)
          }
          @

          1 Reply Last reply
          0
          • B Offline
            B Offline
            Buckets
            wrote on last edited by
            #5

            I'm not sure if currentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* previous) gets triggered if you change the item's position, but it is worth a shot.

            You could also extend the QTreeWidget with a class that holds the current QModelIndex (cur) of the current pointer and the previous position (pre).

            When you do the internal movement set pre =cur, cur = indexFromItem(QTreeWidgtItem).
            Do a check to see if pre != cur or if pre!= some default value, then emit(moved_item(pre, cur)) and set pre to cur or a default value.

            ba ba ba
            ba na na na

            1 Reply Last reply
            0
            • B Offline
              B Offline
              Buckets
              wrote on last edited by
              #6

              sorry for the late response, but I'm glad you got it

              ba ba ba
              ba na na na

              1 Reply Last reply
              0
              • N Offline
                N Offline
                neuviemep
                wrote on last edited by
                #7

                currentItemChanged() gets triggered, but it doesn't refer to the item that moved, but the one that occupies the space that it used to hold, so it's useless. Even more so when you move multiple items.

                I also figured out an another way to figure out the row numbers of the moving items from before and after the move, which is based on indexFromItem() like your suggestion:

                @
                void MyTreeWidget::dropEvent(QDropEvent event)
                {
                // get the list of the items that are about to be dropped
                QList<QTreeWidgetItem
                > dragItems = selectedItems();

                // find out their row numbers before the drop
                QList<int> fromRows;
                QTreeWidgetItem *item;
                foreach(item, dragItems) fromRows.append(indexFromItem(item).row());
                
                // the default implementation takes care of the actual move inside the tree
                QTreeWidget::dropEvent(event);
                
                // query the indices of the dragged items again after the drop
                QList<int> toRows;
                foreach(item, dragItems) toRows.append(indexFromItem(item).row());
                
                // notify subscribers in some useful way
                emit itemsMoved(fromRows, toRows);
                

                }
                @

                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