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. QTableView Versus Row Drag/drop crashes
Forum Updated to NodeBB v4.3 + New Features

QTableView Versus Row Drag/drop crashes

Scheduled Pinned Locked Moved Unsolved General and Desktop
8 Posts 4 Posters 594 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.
  • J Offline
    J Offline
    Jyce
    wrote on last edited by Jyce
    #1

    Hello,

    i'm having trouble understanding how to implement a row drag/drop into my applications. Here are the constraints i have to live with.
    1 - Can't subclass QtableView
    2 - Must drag/drop full rows
    3 - May drag between several views sharing the same model

    The approach is i install an event filter in the Qtableview to get my app to intercept by itself the events, get the ID of the row at the beginning of drag to cut the row using the cut function i already made for context menu, then on drop, insert the row still using the function from the context menu.

    But before dealing with the cut/insert part i need to get the basics for drag/drop.
    I can go up to the dragenter event, but once i move and/or drop the app crash, i'm trying something that probably don't exist or has been deleted already.

    Here is what i tried :
    1 - View configuration and event filter setup

    void QtWidgetsSFIU_Alpha::configureTableViewForRowSelection(QList<QTableView*> tableViews) {
        for (QTableView* tableView : tableViews) {
            tableView->setSelectionMode(QAbstractItemView::SingleSelection);
            tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
        }
    }
    
    void QtWidgetsSFIU_Alpha::configureDragAndDrop(QTableView* view)
    {
        if (view == nullptr)
            return;
       
        // Enable drag and drop for the serial views
        view->viewport()->installEventFilter(this);
        view->setDragEnabled(true);
        view->setAcceptDrops(true);
        view->setDropIndicatorShown(true);
        view->setDragDropMode(QAbstractItemView::InternalMove);
        view->setDefaultDropAction(Qt::MoveAction);
        view->setDragDropOverwriteMode(false);
    
    }
    
    

    2 - I create small functions to manage the mouse events for clean drag and drop

    void QtWidgetsSFIU_Alpha::mouseSerialViewPressEvent(QMouseEvent* event)
    {
        if (event->button() == Qt::LeftButton) {
            dragStartPosition = event->pos();
            qDebug() << "Mouse pressed at " << dragStartPosition;
        }
    
    }
    
    void QtWidgetsSFIU_Alpha::mouseSerialViewMoveEvent(QMouseEvent* event)
    {
        if (!(event->buttons() & Qt::LeftButton)) {
    		qDebug() << "Mouse released at " << event->pos();
            return;
        }
            
    
        if ((event->pos() - dragStartPosition).manhattanLength()
            < QApplication::startDragDistance()){
            qDebug() << "Mouse moved less than " << QApplication::startDragDistance();
            return;
        }
    
        qDebug() << "Draged Started ";
        QDrag* drag = new QDrag(this);
        QMimeData* mimeData = new QMimeData;
    
        mimeData->setText("DragAndDropTest");
        drag->setMimeData(mimeData);
    
        Qt::DropAction dropAction = drag->exec(Qt::CopyAction | Qt::MoveAction);
    
    }
    

    And finally the event filter

    
    /**
         * @brief Filters events if this object has been installed as an event filter for the watched object.
         * @param obj Object being watched.
         * @param event Event received.
         * @return True if the event should be filtered (i.e., stopped); otherwise false.
         */
    bool QtWidgetsSFIU_Alpha::eventFilter(QObject* obj, QEvent* event) {
        
        // Implement event filter for all mouse events
        if (event->type() == QEvent::MouseButtonPress) {
            QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
            mouseSerialViewPressEvent(mouseEvent);
    	}
        else if (event->type() == QEvent::MouseMove) {
            QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
            mouseSerialViewMoveEvent(mouseEvent);
    	}
       
    
        // Drag enter, drage move, drag leave, drop events are handled here
        if (event->type() == QEvent::DragEnter) {
            qDebug() << "DragEnter";
        }
        else if (event->type() == QEvent::DragMove) {
            qDebug() << "DragMove";
        }
        else if (event->type() == QEvent::DragLeave) {
            qDebug() << "DragLeave";
        }
        else if (event->type() == QEvent::Drop) {
            qDebug() << "Drop";
        }
    
    
        // standard event processing
        return QObject::eventFilter(obj, event);
    
    }
    
    

    And this is where I'm having issues, for now, i put dummy MIME data just to check i understand how the events occurs in debug.

    But the app keep crashing, i can see in the console the mouse press, the creation of the drag object, and the capture of the dragenter event, but can't see dragmove or dragleave, and even less drop. Instead something is trying so read a null object somewhere (Console output below)

    Mouse pressed at  QPoint(293,67)
    Mouse moved less than  10
    Mouse moved less than  10
    Mouse moved less than  10
    Mouse moved less than  10
    Mouse moved less than  10
    Draged Started 
    DragEnter
    Exception levée à 0x00007FF97E83A4D4 (Qt6Guid.dll) dans QtWidgetsSFIU_Alpha.exe : 0xC0000005 : Violation d'accès lors de la lecture de l'emplacement 0x0000000000000000.
    

    I'm a bit lost and not sure how to troubleshoot this. Does anybody pointers ?

    Thx
    Jc

    Christian EhrlicherC 1 Reply Last reply
    0
    • J Jyce

      Hello,

      i'm having trouble understanding how to implement a row drag/drop into my applications. Here are the constraints i have to live with.
      1 - Can't subclass QtableView
      2 - Must drag/drop full rows
      3 - May drag between several views sharing the same model

      The approach is i install an event filter in the Qtableview to get my app to intercept by itself the events, get the ID of the row at the beginning of drag to cut the row using the cut function i already made for context menu, then on drop, insert the row still using the function from the context menu.

      But before dealing with the cut/insert part i need to get the basics for drag/drop.
      I can go up to the dragenter event, but once i move and/or drop the app crash, i'm trying something that probably don't exist or has been deleted already.

      Here is what i tried :
      1 - View configuration and event filter setup

      void QtWidgetsSFIU_Alpha::configureTableViewForRowSelection(QList<QTableView*> tableViews) {
          for (QTableView* tableView : tableViews) {
              tableView->setSelectionMode(QAbstractItemView::SingleSelection);
              tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
          }
      }
      
      void QtWidgetsSFIU_Alpha::configureDragAndDrop(QTableView* view)
      {
          if (view == nullptr)
              return;
         
          // Enable drag and drop for the serial views
          view->viewport()->installEventFilter(this);
          view->setDragEnabled(true);
          view->setAcceptDrops(true);
          view->setDropIndicatorShown(true);
          view->setDragDropMode(QAbstractItemView::InternalMove);
          view->setDefaultDropAction(Qt::MoveAction);
          view->setDragDropOverwriteMode(false);
      
      }
      
      

      2 - I create small functions to manage the mouse events for clean drag and drop

      void QtWidgetsSFIU_Alpha::mouseSerialViewPressEvent(QMouseEvent* event)
      {
          if (event->button() == Qt::LeftButton) {
              dragStartPosition = event->pos();
              qDebug() << "Mouse pressed at " << dragStartPosition;
          }
      
      }
      
      void QtWidgetsSFIU_Alpha::mouseSerialViewMoveEvent(QMouseEvent* event)
      {
          if (!(event->buttons() & Qt::LeftButton)) {
      		qDebug() << "Mouse released at " << event->pos();
              return;
          }
              
      
          if ((event->pos() - dragStartPosition).manhattanLength()
              < QApplication::startDragDistance()){
              qDebug() << "Mouse moved less than " << QApplication::startDragDistance();
              return;
          }
      
          qDebug() << "Draged Started ";
          QDrag* drag = new QDrag(this);
          QMimeData* mimeData = new QMimeData;
      
          mimeData->setText("DragAndDropTest");
          drag->setMimeData(mimeData);
      
          Qt::DropAction dropAction = drag->exec(Qt::CopyAction | Qt::MoveAction);
      
      }
      

      And finally the event filter

      
      /**
           * @brief Filters events if this object has been installed as an event filter for the watched object.
           * @param obj Object being watched.
           * @param event Event received.
           * @return True if the event should be filtered (i.e., stopped); otherwise false.
           */
      bool QtWidgetsSFIU_Alpha::eventFilter(QObject* obj, QEvent* event) {
          
          // Implement event filter for all mouse events
          if (event->type() == QEvent::MouseButtonPress) {
              QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
              mouseSerialViewPressEvent(mouseEvent);
      	}
          else if (event->type() == QEvent::MouseMove) {
              QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
              mouseSerialViewMoveEvent(mouseEvent);
      	}
         
      
          // Drag enter, drage move, drag leave, drop events are handled here
          if (event->type() == QEvent::DragEnter) {
              qDebug() << "DragEnter";
          }
          else if (event->type() == QEvent::DragMove) {
              qDebug() << "DragMove";
          }
          else if (event->type() == QEvent::DragLeave) {
              qDebug() << "DragLeave";
          }
          else if (event->type() == QEvent::Drop) {
              qDebug() << "Drop";
          }
      
      
          // standard event processing
          return QObject::eventFilter(obj, event);
      
      }
      
      

      And this is where I'm having issues, for now, i put dummy MIME data just to check i understand how the events occurs in debug.

      But the app keep crashing, i can see in the console the mouse press, the creation of the drag object, and the capture of the dragenter event, but can't see dragmove or dragleave, and even less drop. Instead something is trying so read a null object somewhere (Console output below)

      Mouse pressed at  QPoint(293,67)
      Mouse moved less than  10
      Mouse moved less than  10
      Mouse moved less than  10
      Mouse moved less than  10
      Mouse moved less than  10
      Draged Started 
      DragEnter
      Exception levée à 0x00007FF97E83A4D4 (Qt6Guid.dll) dans QtWidgetsSFIU_Alpha.exe : 0xC0000005 : Violation d'accès lors de la lecture de l'emplacement 0x0000000000000000.
      

      I'm a bit lost and not sure how to troubleshoot this. Does anybody pointers ?

      Thx
      Jc

      Christian EhrlicherC Online
      Christian EhrlicherC Online
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @Jyce said in QTableView Versus Row Drag/drop crashes:

      But the app keep crashing,

      That's why they invented debuggers.

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

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

        Hi and welcome to devnet,

        Strangely, you requirements sounds familiar from some years agol.
        Anyway, one thing I haven't seen from your requirement is that the model class should not be subclassed so what about following the drag and drop part of the item view documentation and customize the model to manage that part so you don't need such hacks ?

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

        J 1 Reply Last reply
        0
        • SGaistS SGaist

          Hi and welcome to devnet,

          Strangely, you requirements sounds familiar from some years agol.
          Anyway, one thing I haven't seen from your requirement is that the model class should not be subclassed so what about following the drag and drop part of the item view documentation and customize the model to manage that part so you don't need such hacks ?

          J Offline
          J Offline
          Jyce
          wrote on last edited by Jyce
          #4

          @SGaist , thanks I'll look at the article, i guess requirements where not complete then :D
          No the goal is to do with what i have and not subclass anything.

          Is the way i'm trying to use is consider too much of a hack as you mentioned ?
          Implementing event filters seemed quit a common practice when i looked for solutions ?
          I still would like to understand what I'm doing wrong here.

          @Christian-Ehrlicher, i would gladly track the issue with the breakpoints if i knew where to start :)
          Putting it in the event handler does not help much as i constantly hit it, and if i filter on event from the table view i'm still ending up. Call stack is not helping much either :)

          b7e4d25f-35cb-443d-8039-c9343ae8d8c8-image.png

          SGaistS 1 Reply Last reply
          0
          • J Jyce

            @SGaist , thanks I'll look at the article, i guess requirements where not complete then :D
            No the goal is to do with what i have and not subclass anything.

            Is the way i'm trying to use is consider too much of a hack as you mentioned ?
            Implementing event filters seemed quit a common practice when i looked for solutions ?
            I still would like to understand what I'm doing wrong here.

            @Christian-Ehrlicher, i would gladly track the issue with the breakpoints if i knew where to start :)
            Putting it in the event handler does not help much as i constantly hit it, and if i filter on event from the table view i'm still ending up. Call stack is not helping much either :)

            b7e4d25f-35cb-443d-8039-c9343ae8d8c8-image.png

            SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #5

            @Jyce out of curiosity, why are subclasses forbidden ?

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

            J 1 Reply Last reply
            0
            • SGaistS SGaist

              @Jyce out of curiosity, why are subclasses forbidden ?

              J Offline
              J Offline
              Jyce
              wrote on last edited by
              #6

              @SGaist it's been a while since i put my hand on GUI with QT, i'm trying to re-learn step by step. working using the default features felt like a good idea but i have the feeling it might be a stoopid :)

              What puzzles me is the fact that combining a provided QTableView and a provided QstandardItem model does not allow drag and drop since for example sorting works right of the bat.

              From what i understand from the doc you recommended me, sub-classing at the model level seems to allow to keep various view in sync with much less work. Or less computation ?

              SGaistS 1 Reply Last reply
              0
              • J Jyce

                @SGaist it's been a while since i put my hand on GUI with QT, i'm trying to re-learn step by step. working using the default features felt like a good idea but i have the feeling it might be a stoopid :)

                What puzzles me is the fact that combining a provided QTableView and a provided QstandardItem model does not allow drag and drop since for example sorting works right of the bat.

                From what i understand from the doc you recommended me, sub-classing at the model level seems to allow to keep various view in sync with much less work. Or less computation ?

                SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #7

                @Jyce I am not following you here. Drag and drop works out of the box for the item views. You just have to activate the options.
                Now you want to do something special so you have to adjust the code to your needs which is nothing unusual.

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

                J 1 Reply Last reply
                1
                • SGaistS SGaist

                  @Jyce I am not following you here. Drag and drop works out of the box for the item views. You just have to activate the options.
                  Now you want to do something special so you have to adjust the code to your needs which is nothing unusual.

                  J Offline
                  J Offline
                  Jyce
                  wrote on last edited by Jyce
                  #8

                  Hello @SGaist, fully agree with you and understand.

                  I wrongly assumed that row drag and drop was part of the baseline behavior of the qtableview :)

                  I'm following the links you sent me and the various example to work on it (the source code of the Qtableview itslef provides a lot of information)

                  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