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. [SOLVED] QTreeWidget drag and drop signals
Forum Updated to NodeBB v4.3 + New Features

[SOLVED] QTreeWidget drag and drop signals

Scheduled Pinned Locked Moved General and Desktop
5 Posts 2 Posters 14.1k 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.
  • G Offline
    G Offline
    glaucos
    wrote on last edited by
    #1

    Hi everyone !

    I've been working with a QTreeWidget for a article editor application. The QTreeWidget shows all opened articles in a tree where articles can be children of others. What I want to do is to dynamically set the parent-child relationship by dragging and dropping articles in the tree view to others.
    I tried to reimplement dropEvent on thre treewidget but it doesn't work with QTreeWidgetItems wich doesn't seem to inherit QWidget.
    I also tried to connect the QTreeWidget::itemChanged() signal to a custom slot but it doesn't seem to be emited on drag and drop operations.
    How should I handle such an event ?

    Thanks in advance !

    1 Reply Last reply
    0
    • raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by
      #2

      please post some code than we can help you more efficiently.

      • Did you try to implement QTreeWidget::dropMimeData() ?
      • did you try treeWidget->setDragDropMode(QAbstractItemView::InternalMove) ?

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      1 Reply Last reply
      0
      • G Offline
        G Offline
        glaucos
        wrote on last edited by
        #3

        Thanks for the fast answer.

        I think dropMimeData() is what i was looking for. However, after implementing it, it still misses something to get it to work.

        Here's the code:

        @
        #ifndef WORKSPACEWIDGET_H
        #define WORKSPACEWIDGET_H

        #include <QTreeWidget>
        #include <QDropEvent>

        class WorkspaceWidget : public QTreeWidget
        {
        Q_OBJECT
        public:
        explicit WorkspaceWidget(QWidget *parent = 0);

        protected:
        virtual bool dropMimeData ( QTreeWidgetItem * parent, int index, const QMimeData * data, Qt::DropAction action );
        void dropEvent(QDropEvent *event);

        };

        #endif // WORKSPACEWIDGET_H
        @
        @
        #include "workspacewidget.h"
        #include <QDropEvent>
        #include <QMessageBox>

        WorkspaceWidget::WorkspaceWidget(QWidget *parent) :
        QTreeWidget(parent)
        {
        QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
        sizePolicy.setHorizontalStretch(0);
        sizePolicy.setVerticalStretch(0);
        sizePolicy.setHeightForWidth(this->sizePolicy().hasHeightForWidth());
        setSizePolicy(sizePolicy);

        setAcceptDrops(true);
        setDragEnabled(true);
        setDragDropMode(QAbstractItemView::InternalMove);
        
        this->setHeaderItem(new QTreeWidgetItem(QStringList("Workspace")));
        

        }

        bool WorkspaceWidget::dropMimeData( QTreeWidgetItem * parent, int index, const QMimeData * data, Qt::DropAction action ){
        QTreeWidget::dropMimeData(parent, index, data, action);
        QMessageBox::information(this, "", parent->text(currentColumn()) + "dropped");

        return true;
        

        }

        void WorkspaceWidget::dropEvent(QDropEvent *event)
        {
        QTreeWidget::dropEvent(event);

        QMessageBox::information(this, "", event->source()->objectName());
        

        }

        @

        I get a message box from the dropEvent, which is empty since QTreeWidgetItem isn't a QWidget, but I don't get any message from dropMimeData() ?

        1 Reply Last reply
        0
        • raven-worxR Offline
          raven-worxR Offline
          raven-worx
          Moderators
          wrote on last edited by
          #4

          Currently in your dropEvent you retrieve the widget which has started the drag (thats your tree widget) and return it's objectName, which is by default an empty string (as long as you haven't explicitly set it).
          But what you want is the data of the drag, which you get with event->mimeData(). This contains the dragged QTreeItems you want.

          I don't know what format the dropData has though, because i never worked with Qt standard item implementations (only used custom models,views,...).
          But you can iterate over all formats of the QMimeData objects using it's methods or you can quickly use the Qt DropSite example to check what mime types the drag has.

          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
          If you have a question please use the forum so others can benefit from the solution in the future

          1 Reply Last reply
          0
          • G Offline
            G Offline
            glaucos
            wrote on last edited by
            #5

            Thank you ! It works.

            Here's the code:

            @

            void WorkspaceWidget::dropEvent(QDropEvent *event)
            {
            //MimeData: application/x-qabstractitemmodeldatalist"

            QTreeWidget::dropEvent(event);
            
            
            const QMimeData* qMimeData = event->mimeData();
            
            QByteArray encoded = qMimeData->data("application/x-qabstractitemmodeldatalist");
            QDataStream stream(&encoded, QIODevice::ReadOnly);
            
            while (!stream.atEnd())
            {
                int row, col;
                QMap<int,  QVariant> roleDataMap;
            
                stream >> row >> col >> roleDataMap;
            
                QString dropped = roleDataMap[0].toString();
            
                QString into = this->itemAt(event->pos())->text(0);
            
                QMessageBox::information(this, "", "DROPPING:" + dropped + "\nINTO:" +
                                         into);
            }
            

            }

            @

            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