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. How to perform an action at the end of a QTableView drag-and-drop operation?
Forum Updated to NodeBB v4.3 + New Features

How to perform an action at the end of a QTableView drag-and-drop operation?

Scheduled Pinned Locked Moved Unsolved General and Desktop
5 Posts 2 Posters 744 Views 2 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.
  • R Offline
    R Offline
    Rodrigo B.
    wrote on last edited by Rodrigo B.
    #1

    I have a QTableView and would like to perform an action after a drag-and-drop operation.

    Originally I've added the action at the end of the model's dropMimeData method:

    bool MyTableView::dropMimeData(...) {
        auto result = super.dropMimeData(...);
        // perform my action
        return result
    }
    

    but that does not work because if I am dragging a row from one point to another, at this point the original row has not yet been deleted, so the table contains two copies of the row at this point, which is an invalid state for my action to be performed. I need to invoke the action only after the row has been completed moved.

    I also tried subclassing QTableView and overriding its dropEvent method:

    void MyTableView::dropEvent(QDropEvent *event) {
        super().dropEvent(event);
        // perform my action
    }
    

    but it turns out that the chain of events caused by the drag & drop is not completed yet when we leave super().dropEvent(event); the removal of the row from its original location happens after MyTableView::dropEvent returns, that is, after my specific action which should happen only after the removal of the row from its original location.

    The failure of overriding dropEvent is particularly puzzling to me because I don't see how super().dropEvent() does not take care of everything before returning.

    Anyway, is there a way or a place where I can hook this action after the whole drag-and-drop operation is completed, including after the removal of the original row?

    JonBJ 1 Reply Last reply
    0
    • R Rodrigo B.

      I have a QTableView and would like to perform an action after a drag-and-drop operation.

      Originally I've added the action at the end of the model's dropMimeData method:

      bool MyTableView::dropMimeData(...) {
          auto result = super.dropMimeData(...);
          // perform my action
          return result
      }
      

      but that does not work because if I am dragging a row from one point to another, at this point the original row has not yet been deleted, so the table contains two copies of the row at this point, which is an invalid state for my action to be performed. I need to invoke the action only after the row has been completed moved.

      I also tried subclassing QTableView and overriding its dropEvent method:

      void MyTableView::dropEvent(QDropEvent *event) {
          super().dropEvent(event);
          // perform my action
      }
      

      but it turns out that the chain of events caused by the drag & drop is not completed yet when we leave super().dropEvent(event); the removal of the row from its original location happens after MyTableView::dropEvent returns, that is, after my specific action which should happen only after the removal of the row from its original location.

      The failure of overriding dropEvent is particularly puzzling to me because I don't see how super().dropEvent() does not take care of everything before returning.

      Anyway, is there a way or a place where I can hook this action after the whole drag-and-drop operation is completed, including after the removal of the original row?

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #2

      @Rodrigo-B
      Unless you get a better specific answer, which has not happened so far, you can always set off a QTimer at the end of dropEvent(), even possibly with a 0 delay, to execute desired code.

      R 1 Reply Last reply
      0
      • JonBJ JonB

        @Rodrigo-B
        Unless you get a better specific answer, which has not happened so far, you can always set off a QTimer at the end of dropEvent(), even possibly with a 0 delay, to execute desired code.

        R Offline
        R Offline
        Rodrigo B.
        wrote on last edited by Rodrigo B.
        #3

        @JonB Thank you! I see, that's a good idea. That should work fine, although it could break if the drag and drop takes longer than my delay. And, if I choose a longer delay to make sure that doesn't happen, then the app is less responsive. But I think it should work pretty well anyway.

        I made do with a little hack for now. I set a doing_drag_and_drop flag inside dropMimeData indicating that a drag-and-drop is underway. It seems that the last thing done by the drag-and-drop is to remove the original rows. So, inside removeRows, if the flag is true I know a drag-and-drop is ending, so I perform my action and set the flag to false. This works, but it is ugly and could break if Qt changes the order of operations in future versions...

        JonBJ 1 Reply Last reply
        0
        • R Rodrigo B.

          @JonB Thank you! I see, that's a good idea. That should work fine, although it could break if the drag and drop takes longer than my delay. And, if I choose a longer delay to make sure that doesn't happen, then the app is less responsive. But I think it should work pretty well anyway.

          I made do with a little hack for now. I set a doing_drag_and_drop flag inside dropMimeData indicating that a drag-and-drop is underway. It seems that the last thing done by the drag-and-drop is to remove the original rows. So, inside removeRows, if the flag is true I know a drag-and-drop is ending, so I perform my action and set the flag to false. This works, but it is ugly and could break if Qt changes the order of operations in future versions...

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #4

          @Rodrigo-B said in How to perform an action at the end of a QTableView drag-and-drop operation?:

          although it could break if the drag and drop takes longer than my delay.

          You would start the timer at the end of dropEvent(), so the time taken for the drag is not included, only the time for whatever "extra" you do at the end.

          R 1 Reply Last reply
          0
          • JonBJ JonB

            @Rodrigo-B said in How to perform an action at the end of a QTableView drag-and-drop operation?:

            although it could break if the drag and drop takes longer than my delay.

            You would start the timer at the end of dropEvent(), so the time taken for the drag is not included, only the time for whatever "extra" you do at the end.

            R Offline
            R Offline
            Rodrigo B.
            wrote on last edited by
            #5

            @JonB But that's the thing, at the end of dropEvent it seems like the drag-and-drop operators are not yet completed (things like removing rows and so on happen after we exit it).

            So that's going to take some unspecified time t and we must set the timer to an interval that is guaranteed to be greater than t. If we guess too low, we run the risk of running the action on an inconsistent state, so we must guess high and that may introduce a bit of a delay.

            Also, does timer use application-time, or wall time? If wall time, then we would not guarantee correctness because in principle the OS may interrupt the application after dropEvent exits but before drag-and-drop is over, and when we resume it the time hits and we run it on an inconsistent state.

            Anyway, this is all pretty academic, I think in practice your solution would work well.

            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