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. Drag and Drop within QTreeWidget
Qt 6.11 is out! See what's new in the release blog

Drag and Drop within QTreeWidget

Scheduled Pinned Locked Moved General and Desktop
3 Posts 2 Posters 4.9k 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.
  • B Offline
    B Offline
    blueshift
    wrote on last edited by
    #1

    Hi all,
    I want to implement a Drag and Drop for QTreeWidget that shows the folder structure with files and folders. I want to drag ONLY FILES and move it into the folder in the same view. When I move over the folder, it should get highlighted for user convenience.

    So I far as from below code, I am able to get the QTreeWidgetItem information for 1 selected file during drag and drop using QDatastream. I m sure the file is getting dragged and dropped properly over the folder.

    However, I have to do with multiple files which I suppose I have to do with QList.
    I am able to get ithe item information on mouse hover. The issues I am facing is I am not getting the highlighted folder on hover. The stylesheet is getting applied after Drop Event occurs. And I want to highlight only when hovering the folder.

    Need help.

    My Code below here:

    @#include <QtGui>
    #include "cloudview.h"

    CloudView::CloudView(QWidget *parent) :
    QTreeWidget(parent)
    {
    setAcceptDrops(true);
    }

    void CloudView::mousePressEvent(QMouseEvent *event)
    {
    qDebug() << "CloudView - MousePressEvent";
    if (event->button() == Qt::LeftButton) {
    startPos = event->pos();
    }

    QTreeWidget::mousePressEvent(event);
    

    }

    void CloudView::mouseMoveEvent(QMouseEvent *event)
    {
    if (event->buttons() & Qt::LeftButton) {
    int distance = (event->pos() - startPos).manhattanLength();
    if (distance >= QApplication::startDragDistance())
    performDrag();
    }

    QTreeWidget::mouseMoveEvent(event);
    

    }

    void CloudView::dragEnterEvent(QDragEnterEvent *event)
    {
    qDebug() << "CloudView - DragEnterEvent";
    CloudView *source = qobject_cast<CloudView *>(event->source());
    if (source) {
    if (event->mimeData()->hasFormat("file/x-temp-files")) {
    event->setDropAction(Qt::MoveAction);
    event->accept();
    }
    else
    event->ignore();
    }
    }

    void CloudView::dragMoveEvent(QDragMoveEvent *event)
    {
    qDebug() << "CloudView - DragMoveEvent";
    CloudView *source = qobject_cast<CloudView *>(event->source());
    if (source) {
    if(event->mimeData()->hasFormat("file/x-temp-files")) {
    QTreeWidgetItem *item = itemAt(event->pos());
    if(item) {
    qDebug() << "itemat: " << item->text(0);
    source->setStyleSheet(QString::fromUtf8("QTreeView::item:hover {\n"
    "background-color: rgb(123, 45, 67);\n"
    "}"));
    }
    else {
    //item->setBackgroundColor(0, QColor(Qt::blue));
    }
    event->setDropAction(Qt::MoveAction);
    event->accept();
    }
    else
    event->ignore();
    }
    }

    void CloudView::dropEvent(QDropEvent *event)
    {
    qDebug() << "CloudView - DropEvent";

    CloudView *source = qobject_cast<CloudView *> (event->source());
    if (source) {
        if (event->mimeData()->hasFormat("file/x-temp-files")) {
            QByteArray appData = event->mimeData()->data("file/x-temp-files");
            QDataStream dataStream(&appData, QIODevice::ReadOnly);
            QTreeWidgetItem item;
            QString str;
            dataStream >> str >> item;
            qDebug() << "str: " << str << "item: " << item.text(0);
    
            //copy item here - to write function
            event->setDropAction(Qt::MoveAction);
            event->accept();
        }
        else
            event->ignore();
    }
    

    }

    void CloudView::dragLeaveEvent(QDragLeaveEvent *event)
    {

    }

    void CloudView::performDrag()
    {
    qDebug() << "CloudView - performDrag";
    QTreeWidgetItem *item = currentItem();

    QByteArray itemData;
    QDataStream dataStream(&itemData, QIODevice::WriteOnly);
    
    if (item) {
        dataStream << item->text(0) << *item;
    
        QMimeData *mimeData = new QMimeData;
        mimeData->setData("file/x-temp-files", itemData);
        mimeData->setText(item->text(0));
    
        QDrag *drag = new QDrag(this);
        drag->setMimeData(mimeData);
        drag->setPixmap(QPixmap(":/Images/edit_copy.png"));
        drag->exec&#40;Qt::MoveAction&#41;;
    }
    

    }

    @

    1 Reply Last reply
    0
    • B Offline
      B Offline
      blueshift
      wrote on last edited by
      #2

      I partially solved this issue .

      1. QTreeWidgetItem setData() - can assign data to item. I use this to assign item whether it is a file or folder
        @ if (!link.isDir())
        item->setData(0, Qt::UserRole, QString("file"));
        else
        item->setData(0, Qt::UserRole, QString("folder"));@

      2. In Drag Move Event
        @if(item->data(0, Qt::UserRole).toString()=="folder")
        setCurrentItem(item);
        @

      Now this is solved just for 1 item. I want to use QList with QDataStream when there are multiple selections. I have the following code in performDrag() function;

      @
      QList<QTreeWidgetItem *> items = selectedItems();

      foreach(QTreeWidgetItem* item, items) {
      dataStream << item;
      }
      @

      But how would I get value from datastream at the other end?

      1 Reply Last reply
      0
      • p3c0P Offline
        p3c0P Offline
        p3c0
        Moderators
        wrote on last edited by
        #3

        If you are going to perform drag and drop inside the same widget then just keep a public QStringList and add all the paths into this list before drag has started and on dropevent access this list, parse it and do whatever operations you want to perform. No need to use QDataStream

        157

        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