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. Reordering TableView with drag and drop
Forum Update on Monday, May 27th 2025

Reordering TableView with drag and drop

Scheduled Pinned Locked Moved Solved General and Desktop
drag and drop ttableviewsetpixmapmoveaction
3 Posts 2 Posters 2.1k 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.
  • P Offline
    P Offline
    PeterPan32
    wrote on 11 Jun 2016, 13:32 last edited by
    #1

    Hi,

    I implemented my own QAbstractListModel and currently its displayed in a standard QTableview.
    I want to allow reordering the elements. Furthermore it must still be possible to drop something from outside the QTableview (no use of setDragDropMode(QAbstractItemView::InternalMove)).
    The model is working properly. But currently items are copyed instead of moved.
    So I need a way to force the QTableview just to create drags as MoveAction and not as CopyAction.

    Either I can do this with any features provieded by the QTableview or I must costumize the view.
    I already tried the second approach:

    void CPlaylistWidget::mouseMoveEvent(QMouseEvent *event)
    {
        if (!(event->buttons() & Qt::LeftButton))
            return;
        if ((event->pos() - dragStartPosition).manhattanLength()
             < QApplication::startDragDistance())
            return;
    
        QDrag *drag = new QDrag(this);
    
        drag->setMimeData(this->model()->mimeData(this->selectionModel()->selectedRows()));
    
        Qt::DropAction dropAction = drag->exec(Qt::MoveAction);
    ....
    }
    

    But now I can't see the moved row during the drag. I know there is the drag->setPixmap method.
    But I don't know how to assign a row of the tableview to that.

    Happy about any suggestions.

    J 1 Reply Last reply 11 Jun 2016, 13:44
    0
    • P PeterPan32
      11 Jun 2016, 13:32

      Hi,

      I implemented my own QAbstractListModel and currently its displayed in a standard QTableview.
      I want to allow reordering the elements. Furthermore it must still be possible to drop something from outside the QTableview (no use of setDragDropMode(QAbstractItemView::InternalMove)).
      The model is working properly. But currently items are copyed instead of moved.
      So I need a way to force the QTableview just to create drags as MoveAction and not as CopyAction.

      Either I can do this with any features provieded by the QTableview or I must costumize the view.
      I already tried the second approach:

      void CPlaylistWidget::mouseMoveEvent(QMouseEvent *event)
      {
          if (!(event->buttons() & Qt::LeftButton))
              return;
          if ((event->pos() - dragStartPosition).manhattanLength()
               < QApplication::startDragDistance())
              return;
      
          QDrag *drag = new QDrag(this);
      
          drag->setMimeData(this->model()->mimeData(this->selectionModel()->selectedRows()));
      
          Qt::DropAction dropAction = drag->exec(Qt::MoveAction);
      ....
      }
      

      But now I can't see the moved row during the drag. I know there is the drag->setPixmap method.
      But I don't know how to assign a row of the tableview to that.

      Happy about any suggestions.

      J Offline
      J Offline
      Joel Bodenmann
      wrote on 11 Jun 2016, 13:44 last edited by Joel Bodenmann 6 Nov 2016, 13:45
      #2

      You can use QWidget::render() to create the pixmap that you can assign to your QDrag object. You can retrieve the rectangle of your item by using QAbstractItemView::visualRect().

      Something like this (untested):

      void CPlaylistWidget::mouseMoveEvent(QMouseEvent *event)
      {
      	...
      
      	// Retrieve the selected index
      	const QModelIndex& index = currentIndex();
      
      	// Render the pixmap
      	QPixmap pixmap;
      	render(&pixmap, visualRect(index));
      
      	// Create the drag
          QDrag* drag = new QDrag(this);
      	drag->setPixmap(pixmap);
      
      	// Perform the drag
          switch (drag->exec(Qt::MoveAction)) {
      
      	}
      
      	...
      }
      

      You should be able to easily adopt that to allow dragging multiple items at once. Obviously you would want to do some sanity checks along the way (eg. checking the rectangle returned by visualRect()).

      I hope that helps.

      Industrial process automation software: https://simulton.com
      Embedded Graphics & GUI library: https://ugfx.io

      1 Reply Last reply
      1
      • P Offline
        P Offline
        PeterPan32
        wrote on 11 Jun 2016, 18:00 last edited by PeterPan32
        #3

        Sounds great, but I get some runtime error:

        QPainter::begin: Paint device returned engine == 0, type: 2
        QWidget::render: Cannot render with an inactive painter
        

        Edit:
        There is some modification on your suggested code neccessary:

        const QModelIndex& index = currentIndex();
        
        // Render the pixmap
        QPixmap pixmap(visualRect(index).size());
        //pixmap.
        render(&pixmap, QPoint(), visualRect(index));
        
        // Create the drag
        QDrag* drag = new QDrag(this);
        drag->setPixmap(pixmap);
        ...
        

        But anyhow it renders the cell of one index above the selected one.
        Maybe that has something to do with the offset parameter (second one in render).

        Edit2:
        The proper QRect can be calculated with the height of the horizontal header:

        render(&pixmap, QPoint(0,0), visualRect(index).translated(0, horizontalHeader()->height() ));
        
        1 Reply Last reply
        0

        1/3

        11 Jun 2016, 13:32

        • Login

        • Login or register to search.
        1 out of 3
        • First post
          1/3
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved