Qt Forum

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

    Update: Forum Guidelines & Code of Conduct


    Qt World Summit: Early-Bird Tickets

    Unsolved How to do post drag-drop processing in QTableView with custom model

    General and Desktop
    5
    8
    700
    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.
    • J
      JohnGa last edited by JohnGa

      Hello,
      I have a QTableView backed by a custom model MyModel (a subclass of QAbstractTableModel). In MyModel, I have overriden:

      bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) 
      {
            //My code
      
            bool returnVal = QAbstractTableModel::dropMimeData(data, action, row, 0, parent);
      
           //My code
      
           return returVal;
      }
      

      I have to call the superclass dropMimeData method, else I end up with duplicate rows.

      After MyModel::dropMimeData has finished, there is more additional steps the Qt framework does to complete the drag-drop of the rows.

      I want to implement actions after the drag-drop is complete. Is there some facility that I can use to execute code after the drag-drop is complete?

      Thanks.

      1 Reply Last reply Reply Quote 0
      • Pradeep P N
        Pradeep P N last edited by

        Hi @JohnGa

        Have you enabled the drag and drop ?

        dragEnabled and acceptDrops.

        tableView->setEnableDrags(true)
        tableView->setAcceptDrops(true)
        

        Pradeep Nimbalkar.
        Upvote the answer(s) that helped you to solve the issue...
        Keep code clean.

        1 Reply Last reply Reply Quote 1
        • J
          JohnGa last edited by JohnGa

          @Pradeep-P-N

          Yes, my drag-drop row moves are working fine. After MyModel::dropMimeData has finished, the Qt framework does more cleanup of the model. So, the drag-drop is NOT complete at the end of MyModel::dropMimeData.

          I want to execute code that will operate on all the rows in the model, after the drag-drop is complete. I am trying to figure out how I can execute code after the drag-drop is complete.

          Let's say I start with:
          Position-1 -> Row-1
          Position-2 -> Row-2
          Position-3 -> Row-3

          In the UI, I drag-drop Row-1 to be as follows:
          Position-1 -> Row-2
          Position-2 -> Row-1
          Position-3 -> Row-3

          When the above drag-drop of Row-1 is done in the UI, the code executes MyModel::dropMimeData. At the end of that MyModel::dropMimeData, the model collection looks like this:
          Row-1
          Row-2
          Row-1
          Row-3

          After, the Qt framework executes more framework code after MyModel:dropMimeData, them model collection looks like this:
          Row-2
          Row-1
          Row-3.

          I am trying to figure out what I need to do to execute a piece of code after the drag-drop is complete.

          1 Reply Last reply Reply Quote 0
          • Christian Ehrlicher
            Christian Ehrlicher Lifetime Qt Champion last edited by

            For example just emit a signal, add a queued connection and do your work there.

            Qt has to stay free or it will die.

            1 Reply Last reply Reply Quote 5
            • SGaist
              SGaist Lifetime Qt Champion last edited by

              Hi,

              In addition to @Christian-Ehrlicher, QtConcurrent might also be of interest.

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

              1 Reply Last reply Reply Quote 1
              • J
                JohnGa last edited by JohnGa

                Thanks to everyone that is trying to help me. At a very high level, I want to execute code after drag-drop is complete within a QTableView, and the rows in my model have been re-arranged as per the new order. I have a custom model MyTableViewModel behind a QTableView. To implement my drag-drop, I implemented the dropMimeData method which does nothing but calling the "QAbstractTableModel::dropMimeData".

                Let's say I start with:
                Position 1 -> Row1
                Position 2 -> Row2
                Position 3 -> Row3.

                After I drag-drop Row1, from my debugging, I can see it first calling my dropMimeData method. This is "Stack 1" in the attached picture.

                After my dropMimeData is complete, the collection in MyTableViewModel shows:
                Row 1
                Row 2
                Row 1
                Row 3

                Then the Qt Framework calls the removeRows method in MyTableViewModel and cleans up. This is "Stack 2" in the attached picture. After this, the collection correctly shows:
                Row 2
                Row 1
                Row 3

                From the debug stackframes it looks like the Qt framework is has two separate events coming through when drag-drop happens. How can I recognize that both the phases are complete and then execute a piece of code?

                I see the suggestion about raising a custom signal. Where would I raise the signal after the drag-drop is complete?

                0_1560290543822_Qt issue.png

                1 Reply Last reply Reply Quote 0
                • SGaist
                  SGaist Lifetime Qt Champion last edited by

                  What processing do you do that requires that precision ?

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

                  1 Reply Last reply Reply Quote 1
                  • VRonin
                    VRonin last edited by VRonin

                    add a signal: void afterDrop();

                    bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) 
                    {
                         const bool returnVal = QAbstractTableModel::dropMimeData(data, action, row, 0, parent);
                         QTimer::singleShot(0,this,&MyModel::afterDrop);
                         return returVal;
                    }
                    

                    Now any slot connected to the afterDrop signal should be executed after everything completed

                    "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 Reply Quote 1
                    • First post
                      Last post