Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Drag-and-drop row from one table to a single cell of another table



  • Hi,

    I'm getting started with drag-and-drop mechanism.
    I have two QTableView with QStandardItemModel. For these tables I set selection mode rows only:

        setSelectionBehavior(QAbstractItemView::SelectRows);
        setSelectionMode(QAbstractItemView::SingleSelection);
    

    My task is:

    1. take row from table1
    2. analyze data in each cell of the row and convert it to a sigle QString
    3. set this QString data into one of the already existing cells of table2

    To do so I inherited from QTableView and I'm trying to see the text from the QMimeData in debug mode. But it is empty in reimplemented dragMoveEvent and dropEvent (even I can see that I drag selected row).

    How can I get data from cells during drag-and-drop?
    My reimplemented drag and drop TableView:

    #include "tableview.h"
    
    #include <QDropEvent>
    #include <QMimeData>
    
    TableView::TableView(QWidget* parent) :
        QTableView(parent)
    {
        setDragEnabled(true);
        setAcceptDrops(true);
        setDropIndicatorShown(true);
    
        setSelectionBehavior(QAbstractItemView::SelectRows);
        setSelectionMode(QAbstractItemView::SingleSelection);
    }
    
    void TableView::dragMoveEvent(QDragMoveEvent *event){
        const QMimeData *mime = event->mimeData();
        QString txt = mime->text();
        QString html = mime->html();
    }
    
    void TableView::dropEvent (QDropEvent *event){
        const QMimeData *mime = event->mimeData();
        QString txt = mime->text();
        QString html = mime->html();
    }
    

    a7bc9f24-3ead-4dae-af9f-c712fb3ac165-image.png


  • Lifetime Qt Champion

    @Please_Help_me_D said in Drag-and-drop row from one table to a single cell of another table:

    Or probably I need to simply override some of those events and set mimedata there?

    all the functions you mention are on the drop site, not the drag site as you can see in the same documentation, some lines below... https://doc.qt.io/qt-5/dnd.html#dropping - so how should they help filling the mime data on the site where you want to start the drag?


  • Lifetime Qt Champion

    So where do you fill the mime data?
    See https://doc.qt.io/qt-5/dnd.html#dragging



  • @Christian-Ehrlicher I haven't set it.
    Do I need to override QTableView::mousePressEvent() if QTableView has drag and drop events like:

    dragEnterEvent(QDragEnterEvent *)
    dragLeaveEvent(QDragLeaveEvent *)
    dragMoveEvent(QDragMoveEvent *)
    dropEvent(QDropEvent *)
    

    ? Or probably I need to simply override some of those events and set mimedata there?


  • Lifetime Qt Champion

    @Please_Help_me_D said in Drag-and-drop row from one table to a single cell of another table:

    Or probably I need to simply override some of those events and set mimedata there?

    all the functions you mention are on the drop site, not the drag site as you can see in the same documentation, some lines below... https://doc.qt.io/qt-5/dnd.html#dropping - so how should they help filling the mime data on the site where you want to start the drag?



  • @Christian-Ehrlicher ok I'm starting to understand
    I need a little time to make my mind



  • I solved my problem by reimplementing MyTableView::dropEvent(QDropEvent *event).
    Here it is:

    void MyTableView::dropEvent(QDropEvent *event){
        const QMimeData *mime = event->mimeData();
        QStringList typeList = model()->mimeTypes();
    
        if (typeList.isEmpty())
            return;
    
        int sourceRow, sourceCol;
        QByteArray encodedData = mime->data(typeList[0]); // retrieve first row and col from first selectem item
        QDataStream stream(&encodedData, QIODevice::ReadOnly);
        stream >> sourceRow >> sourceCol;
    
        QTableView* sourceTableView = qobject_cast<QTableView*>
                (event->source()); // get tableview from item goes
    
        if (sourceTableView == nullptr)
            return;
    
    // as a result we have source table view, current table view, row and col of dragged item. That is enough to process dragged data and paste it to current model
    }
    

Log in to reply