Drag & drop in QTreeWidget



  • Hello ! :)

    (Sorry for my english)

    I am currently trying to make a drag & drop in a QTreeWidget. So I put the corresponding settings and the method dropEvent :

    class TreeWidget : public QTreeWidget
    {
    protected:
    
      virtual void dropEvent(QDropEvent *event) override
      {
        QModelIndex index = indexAt(event->pos());
        if (!index.isValid()) {  // just in case
          event->setDropAction(Qt::IgnoreAction);
          return;
        }
    
        QTreeWidgetItem* item = itemFromIndex(index);
        qDebug() << "drop on item" << item->text(0);
    
        QTreeWidget::dropEvent(event);
      }
    };
    
    int main()
    {
      TreeWidget *listWidget = new TreeWidget;
      listWidget->setSelectionMode(QAbstractItemView::SingleSelection);
      listWidget->setDragEnabled(true);
      listWidget->viewport()->setAcceptDrops(true);
      listWidget->setDropIndicatorShown(true);
      listWidget->setDragDropMode(QAbstractItemView::InternalMove);
    }
    

    But in my case, I would like to move only parent items. In the code, I get the destination item, but how get dragged item ?

    Have I to overload a drag method ? Launch the drag myself from mousePressEvent ? What is the best way to do ?

    Thanks !


  • Moderators

    @Maluna34 http://doc.qt.io/qt-5/qdropevent.html#source should be what you're looking for.



  • @jsulm Thank you but I can't cast QObject to QTreeWidgetItem. :/


  • Moderators

    @Maluna34 You can (if it is a QTreeWidgetItem). And it is QObject* not QObject.
    Take a look at http://doc.qt.io/qt-5/qobject.html#qobject_cast


  • Moderators

    @jsulm
    source() only returns a widget of the same application as the docs clearly say.

    The QTreeWidgetItem data is "encoded" in the drop-data (QMimeData) itself.
    See source of QStandardItemModel::dropMimeData() and QStandardItemModelPrivate::decodeDataRecursive()
    So unfortunately this is not accessible via public API.



  • @raven-worx Thank you ! Indeed, I manage to get the item text with this code :

    virtual void dropEvent(QDropEvent *event) override
    {
            QString format = event->mimeData()->formats().at(0);
            QByteArray data = event->mimeData()->data(format);
            QDataStream stream(&data, QIODevice::ReadOnly);
    
            int r, c;
            QStandardItem *sitem = new QStandardItem;
            stream >> r >> c >> *sitem;
    
            qDebug() << r << "-" << c << sitem->text();
    }
    

    I think it's correct. Maybe it's also possible to get either the depth of the element or get the right type (QTreeWidgetItem).



  • The best way seems to use QDropEvent::source to get the QTreeWidget and use currentItem() on it. :)



Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.