Modified the mousePressEvent in DragWidget to temporarily detach the dragged QLabel from its parent using setParent(nullptr). This ensures the dragged widget remains visible and above other widgets during the drag operation. Re-parenting logic was added to restore the QLabel to its o riginal container if the drag action is not a MoveAction. This change addresses visual issues where dragged items could disappear behind overlapping widgets, enhancing user experience and maintaining consistent behavior. Task-number: QTBUG-123777 Pick-to: 6.6.2 Change-Id: I3edce9c96815e32eb8f00b61f7eda1709de04b4d Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
127 lines
3.4 KiB
C++
127 lines
3.4 KiB
C++
// Copyright (C) 2016 The Qt Company Ltd.
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
|
|
|
#include <QtWidgets>
|
|
|
|
#include "dragwidget.h"
|
|
|
|
//! [0]
|
|
DragWidget::DragWidget(QWidget *parent)
|
|
: QFrame(parent)
|
|
{
|
|
setMinimumSize(200, 200);
|
|
setFrameStyle(QFrame::Sunken | QFrame::StyledPanel);
|
|
setAcceptDrops(true);
|
|
|
|
QLabel *boatIcon = new QLabel(this);
|
|
boatIcon->setPixmap(QPixmap(":/images/boat.png"));
|
|
boatIcon->move(10, 10);
|
|
boatIcon->show();
|
|
boatIcon->setAttribute(Qt::WA_DeleteOnClose);
|
|
|
|
QLabel *carIcon = new QLabel(this);
|
|
carIcon->setPixmap(QPixmap(":/images/car.png"));
|
|
carIcon->move(100, 10);
|
|
carIcon->show();
|
|
carIcon->setAttribute(Qt::WA_DeleteOnClose);
|
|
|
|
QLabel *houseIcon = new QLabel(this);
|
|
houseIcon->setPixmap(QPixmap(":/images/house.png"));
|
|
houseIcon->move(10, 80);
|
|
houseIcon->show();
|
|
houseIcon->setAttribute(Qt::WA_DeleteOnClose);
|
|
}
|
|
//! [0]
|
|
|
|
void DragWidget::dragEnterEvent(QDragEnterEvent *event)
|
|
{
|
|
if (event->mimeData()->hasFormat("application/x-dnditemdata")) {
|
|
if (event->source() == this) {
|
|
event->setDropAction(Qt::MoveAction);
|
|
event->accept();
|
|
} else {
|
|
event->acceptProposedAction();
|
|
}
|
|
} else {
|
|
event->ignore();
|
|
}
|
|
}
|
|
|
|
void DragWidget::dragMoveEvent(QDragMoveEvent *event)
|
|
{
|
|
if (event->mimeData()->hasFormat("application/x-dnditemdata")) {
|
|
if (event->source() == this) {
|
|
event->setDropAction(Qt::MoveAction);
|
|
event->accept();
|
|
} else {
|
|
event->acceptProposedAction();
|
|
}
|
|
} else {
|
|
event->ignore();
|
|
}
|
|
}
|
|
|
|
void DragWidget::dropEvent(QDropEvent *event)
|
|
{
|
|
if (event->mimeData()->hasFormat("application/x-dnditemdata")) {
|
|
QByteArray itemData = event->mimeData()->data("application/x-dnditemdata");
|
|
QDataStream dataStream(&itemData, QIODevice::ReadOnly);
|
|
|
|
QPixmap pixmap;
|
|
QPoint offset;
|
|
dataStream >> pixmap >> offset;
|
|
|
|
QLabel *newIcon = new QLabel(this);
|
|
newIcon->setPixmap(pixmap);
|
|
newIcon->move(event->position().toPoint() - offset);
|
|
newIcon->show();
|
|
newIcon->setAttribute(Qt::WA_DeleteOnClose);
|
|
|
|
if (event->source() == this) {
|
|
event->setDropAction(Qt::MoveAction);
|
|
event->accept();
|
|
} else {
|
|
event->acceptProposedAction();
|
|
}
|
|
} else {
|
|
event->ignore();
|
|
}
|
|
}
|
|
|
|
//! [1]
|
|
void DragWidget::mousePressEvent(QMouseEvent *event)
|
|
{
|
|
QLabel *child = static_cast<QLabel*>(childAt(event->position().toPoint()));
|
|
if (!child)
|
|
return;
|
|
|
|
QPixmap pixmap = child->pixmap();
|
|
|
|
QByteArray itemData;
|
|
QDataStream dataStream(&itemData, QIODevice::WriteOnly);
|
|
dataStream << pixmap << QPoint(event->position().toPoint() - child->pos());
|
|
//! [1]
|
|
|
|
//! [2]
|
|
QMimeData *mimeData = new QMimeData;
|
|
mimeData->setData("application/x-dnditemdata", itemData);
|
|
//! [2]
|
|
|
|
//! [3]
|
|
QDrag *drag = new QDrag(this);
|
|
drag->setMimeData(mimeData);
|
|
drag->setPixmap(pixmap);
|
|
drag->setHotSpot(event->position().toPoint() - child->pos());
|
|
//! [3]
|
|
|
|
child->setParent(nullptr);
|
|
|
|
if (drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction) == Qt::MoveAction) {
|
|
delete child;
|
|
} else {
|
|
child->setParent(this);
|
|
child->move(event->position().toPoint() - drag->hotSpot());
|
|
child->show();
|
|
}
|
|
}
|