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

Draggable ItemWidget in treeWidget



  • I have set itemWidget ( QPushButton ) to my treeWidget but I cannot drag and drop for the treeWidgetItem. As I want to swap the item between two treeWidgets with custom itemWidget ( QPushButton ) . Is there any ways and any things to set for me to make it become draggable? Or i need create a draggable button? Also, is there any examples for me? Thank you very much.



  • @clementNg

    You have to set flags for your treeWidgetItem.

    yourTreeItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled);
    

    You also have to set the "Drop"-flag for your root-item (where you want to drop your treeItems i.e. your buttons).



  • @Pl45m4
    Thank you. But my itemWidget still cannot drag and drop after I have tried your method. Is there any other suggestation? Thanks.


  • Qt Champions 2019

    Then please show us some your code, best would be a complete small example which shows your problem.



  • @Christian-Ehrlicher

    This is my custom TreeWidget and i would emit the signal if they trigger the corresponding event

    DragDropTreeWidget::DragDropTreeWidget(QWidget *parent) : QTreeWidget(parent)
    {
        setAcceptDrops(true);
        this->m_isDragRemoveItem = false;
    }
    
    void DragDropTreeWidget::mousePressEvent(QMouseEvent *event)
    {
        qDebug() << "mousePressEvent";
        if (event->button() == Qt::LeftButton) {
            startPoint = event->pos();
        }
        QTreeWidget::mousePressEvent(event);
    }
    
    void DragDropTreeWidget::mouseMoveEvent(QMouseEvent *event)
    {
        qDebug() << "mouseMoveEvent";
        QTreeWidget::mouseMoveEvent(event);
    }
    
    void DragDropTreeWidget::dragEnterEvent(QDragEnterEvent *event)
    {
        qDebug() << "dragEnterEvent";
        DragDropTreeWidget *source =
                qobject_cast<DragDropTreeWidget *>(event->source());
        if (source && source != this) {
            event->setDropAction(Qt::MoveAction);
            event->accept();
        }
    }
    
    void DragDropTreeWidget::dragLeaveEvent(QDragLeaveEvent *event)
    {
        qDebug() << "dragLeaveEvent";
        QTreeWidget::dragLeaveEvent(event);
        emit dragLeaveEventAction();
    }
    
    void DragDropTreeWidget::dragMoveEvent(QDragMoveEvent *event)
    {
        qDebug() << "dragMoveEvent";
        DragDropTreeWidget *source =
                qobject_cast<DragDropTreeWidget *>(event->source());
        if (source && source != this) {
            emit dragMoveEventAction(event->pos());
        }
    }
    
    void DragDropTreeWidget::dropEvent(QDropEvent *event)
    {
        qDebug() << "dropEvent";
        DragDropTreeWidget *source =
                qobject_cast<DragDropTreeWidget *>(event->source());
        if (source && source != this) {
            emit dropEventAction();
        }
    }
    
    
    

    Currently , I am trying to create a custom pushButton which is close to the above class to handle the pushbutton drag event. As I am still trying to implement it, it is not completed. However, using dragEnterEvent as an example, i cannot get event->source() after drag the button and it crashed. Also some of the action between the treeWidget and pushbutton would be duplicated and I dun know which one should be needed?

    DragDropPushButton::DragDropPushButton(QWidget *parent)
        : QPushButton(parent)
    {
        this->setAcceptDrops(true);
    }
    
    void DragDropPushButton::mousePressEvent(QMouseEvent *event)
    {
    
        qDebug() << "button mousePressEvent";
        startPoint = event->pos();
        DragDropPushButton* source = this;
        qDebug() << "button name: " + source->text();
        quintptr address=(quintptr)source;
        QByteArray byteArray(QString::number(address).toLatin1());
    
    
    //    QByteArray byteArray(reinterpret_cast<char*>(&source),sizeof(QWidget*));
        QDrag *drag = new QDrag(this);
        QMimeData * mimeData = new QMimeData;
        mimeData->setData("button",byteArray);
        drag->setMimeData(mimeData);
    
        QPoint globalPos = mapToGlobal(event->pos());
        QPoint p = source->mapFromGlobal(globalPos);
        drag->setHotSpot(p);
        drag->setPixmap(source->grab());
        drag->exec(Qt::CopyAction | Qt::MoveAction);
    
        QPushButton::mousePressEvent(event);
    }
    
    void DragDropPushButton::mouseMoveEvent(QMouseEvent *event)
    {
        qDebug() << "button mouseMoveEvent";
        QPushButton::mouseMoveEvent(event);
    }
    
    void DragDropPushButton::dragEnterEvent(QDragEnterEvent *event)
    {
        DragDropPushButton *source;
        if(event->source() != nullptr) {
            source = qobject_cast<DragDropPushButton *>(event->source());
        } else {
            source = qobject_cast<DragDropPushButton *>(this);
        }
        if (source && source != this) {
            event->setDropAction(Qt::MoveAction);
            event->accept();
        }
    }
    
    voidDragDropPushButton::dragLeaveEvent(QDragLeaveEvent *event)
    {
        qDebug() << "dragLeaveEvent";
        QPushButton::dragLeaveEvent(event);
    //    emit dragLeaveEventAction();
    }
    
    void DragDropPushButton::dragMoveEvent(QDragMoveEvent *event)
    {
        DragDropPushButton *source;
        if(event->source() != nullptr) {
            source = qobject_cast<DragDropPushButton *>(event->source());
        } else {
            source = qobject_cast<DragDropPushButton *>(this);
        }
    }
    
    void DragDropPushButton::dropEvent(QDropEvent *event)
    {
        qDebug() << "button dropEvent";
        if (event->mimeData()->hasFormat("button")) {
    
            QByteArray pieceData = event->mimeData()->data("button");
            DragDropPushButton * button = reinterpret_cast<DragDropPushButton*>((ChartsChartsDesignFormDragDropPushButton*)pieceData.toULongLong());
            qDebug() << "button Name : " + button->text();
    
            event->setDropAction(Qt::MoveAction);
            event->accept();
    
        }
    }
    
    


  • @clementNg said in Draggable ItemWidget in treeWidget:

    ChartsChartsDesignFormDragDropPushButton

    Why you are using a class name this long? :o
    It doesnt increase the readability of your code :)



  • @Pl45m4
    oh sorry. Changed to be a shorter name


Log in to reply