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. Problem with special drag'n'drop with QTreeView and custom model
QtWS25 Last Chance

Problem with special drag'n'drop with QTreeView and custom model

Scheduled Pinned Locked Moved Unsolved General and Desktop
drag and dropqtreeviewdropdrag
10 Posts 3 Posters 7.6k 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.
  • V Offline
    V Offline
    voltron
    wrote on last edited by
    #1

    I have a custom model derived from QAbstractItemModel. This model implements dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) method.

    Model assigned to the custom view widget, inheritted from QTreeView. Now I want to implement drag'n'drop of the view's items but in special way. First, when items is dragged inside same view, they should be just moved (e.g. to reorder items within tree). But when item dragged outside the view both copy and move actions should be proposed, so the host widget can choose what to do with dropped item (copy or move it).

    First I defined supported drop actions for a model

     Qt::DropActions MyTreeModel::supportedDropActions() const
     {
      return Qt::CopyAction | Qt::MoveAction;
     }
    

    And then reimplement dropEvent() handler in my view

    void MyTreeView::dropEvent(QDropEvent *event)
    {
      // if we dragging in the same view than actually we want to move
      if ( event->source() == this && event->proposedAction() == Qt::CopyAction)
      {
         event->setDropAction(Qt::MoveAction);
      }
      event->accept();
      QTreeView::dropEvent(event);
    

    But it does not works this way. When I drop item inside same view it completely disappeared. What I missed or doing wrong?

    P.S. sorry for my English, it is not my native language.

    1 Reply Last reply
    0
    • raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by
      #2

      the model implementation is the interesting part here.
      Maybe you also want to read this thread for some clarification.

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

      V 1 Reply Last reply
      0
      • raven-worxR raven-worx

        the model implementation is the interesting part here.
        Maybe you also want to read this thread for some clarification.

        V Offline
        V Offline
        voltron
        wrote on last edited by
        #3

        @raven-worx thanks for the reply.
        In my model I already have implemented mimeData(), mimeTypes(), dropMimeData() and supportedDropActions(). Until I tried to implement this special drag'n'drop case all worked fine: in supportedDropActions() i have only Qt::MoveAction and there is no need in the overloaded dropEvent(). Items moved inside view as expected.

        Now I can not figure out how to enable move only inside same view widget and allow both move and copy when dragging items outside view to another view.

        raven-worxR 1 Reply Last reply
        0
        • V voltron

          @raven-worx thanks for the reply.
          In my model I already have implemented mimeData(), mimeTypes(), dropMimeData() and supportedDropActions(). Until I tried to implement this special drag'n'drop case all worked fine: in supportedDropActions() i have only Qt::MoveAction and there is no need in the overloaded dropEvent(). Items moved inside view as expected.

          Now I can not figure out how to enable move only inside same view widget and allow both move and copy when dragging items outside view to another view.

          raven-worxR Offline
          raven-worxR Offline
          raven-worx
          Moderators
          wrote on last edited by raven-worx
          #4

          @voltron
          ok now i think i got you.

          You almost had it. You should rather call event->setDropAction(Qt::MoveAction); in the dragEnter() event handler than in the dropEvent() handler.
          And return copy and move actions in your model.

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

          V 1 Reply Last reply
          0
          • raven-worxR raven-worx

            @voltron
            ok now i think i got you.

            You almost had it. You should rather call event->setDropAction(Qt::MoveAction); in the dragEnter() event handler than in the dropEvent() handler.
            And return copy and move actions in your model.

            V Offline
            V Offline
            voltron
            wrote on last edited by
            #5

            @raven-worx

            thanks a lot for your help and time. I tried to follow your suggestion. In my model both actions are supported, as defined by supportedDropActions() method

            Qt::DropActions MyTreeModel::supportedDropActions() const
            {
              return Qt::CopyAction | Qt::MoveAction;
            }
            

            Also I removed dropEvent() handler from my view and added instead dragEnterEvent() handler with following implementation

            void MyTreeView::dragEnterEvent( QDragEnterEvent * event )
            {
              event->setDropAction( Qt::MoveAction );
              event->accept();
            }
            

            Unfortunatelly this does not works as I want. I can drag items inside my view, but they are copied not moved. Maybe I missed something or misunderstood you?

            The good thing is that I can also copy items to other views. Still need to restrict drag operations to move only when this drag'n'drop happens inside same view.

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

              Hi and welcome to devnet,

              It should rather be Qt::InternalMove when you want to move a row inside a view. Since you have a custom model, are you implementing the move related methods ?

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

              V 1 Reply Last reply
              0
              • SGaistS SGaist

                Hi and welcome to devnet,

                It should rather be Qt::InternalMove when you want to move a row inside a view. Since you have a custom model, are you implementing the move related methods ?

                V Offline
                V Offline
                voltron
                wrote on last edited by
                #7

                @SGaist thanks for our reply!
                As I understand Qt::InternalMove forbid moving/copying view items from/to other views. Am I right?

                My model is custom, but it is based on the QAbstractItemModel and all important methods are implemented (e.g. data(), dropMimeData()). Also initially it has support only for moving items because in supportedDropActions() I have only Qt::MoveAction enabled and move operation worked fine. So I think all methods required for moving works.

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

                  You can return more than one action in supportedDropActions()

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

                  V 1 Reply Last reply
                  0
                  • SGaistS SGaist

                    You can return more than one action in supportedDropActions()

                    V Offline
                    V Offline
                    voltron
                    wrote on last edited by
                    #9

                    @SGaist
                    yes, I know. Let me explain again.
                    Initially I have custom model where supportedDropActions() returns only Qt::MoveAction, so it is possible only move items when dragging them outside view. This works fine, item dragged and moved nicely to other views and inside same view (reordering).
                    But now I want to implement following behavior. When item is dragged and dropped inside view — just move it (reorder). When item moved outside view — allow both operations copy and move. In same time I want to be able to copy/move items in both directions from my custom view to other views and from other views to my custom view.

                    It is very easy to allow copy and move operations, just to return corresponding flags in supportedDropActions(). And I have it in my code

                    Qt::DropActions MyTreeModel::supportedDropActions() const
                    {
                      return Qt::CopyAction | Qt::MoveAction;
                    }
                    

                    But if I only change supportedDropActions() I can not move items inside my custom view, they copied. But when dragging items to other views I can choose what to do copy or move.

                    There is a Qt::InternalMove flag which looks like a solution. But as I understand Qt::InternalMove forbids moving/copying view items from/to other views. Please correct me if I'm wrong.

                    So now i'm looking for solution which will allow me to only move items inside my custom view and in same time move and copy items from/to other views.

                    1 Reply Last reply
                    0
                    • V Offline
                      V Offline
                      voltron
                      wrote on last edited by
                      #10

                      Well, I found solution. It is very simple, all I need is to set default drop action for my view class as Qt::MoveAction and return copy and move in the suporrtedDropActions().

                      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