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.
-
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).
-
Then please show us some your code, best would be a complete small example which shows your problem.
-
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 :)