En esta página

Ejemplo de Draggable Icons

El ejemplo de Draggable Icons muestra cómo arrastrar y soltar datos de imagen entre widgets en la misma aplicación, y entre diferentes aplicaciones.

Aplicación con iconos que responden a eventos de arrastrar y soltar

En muchas situaciones en las que se utiliza la función arrastrar y soltar, el usuario empieza arrastrando desde un widget concreto y suelta la carga en otro widget. En este ejemplo, subclasificamos QLabel para crear etiquetas que utilizamos como fuentes de arrastre, y las colocamos dentro de QWidgets que sirven tanto de contenedores como de sitios de soltar.

Además, cuando se produce una operación de arrastrar y soltar, queremos enviar algo más que una imagen. También queremos enviar información sobre dónde hizo clic el usuario en la imagen para que pueda colocarla con precisión en el objetivo de la operación de arrastrar y soltar. Este nivel de detalle significa que debemos crear un tipo MIME personalizado para nuestros datos.

Definición de la clase DragWidget

Los widgets de iconos que utilizamos para mostrar iconos son subclases de QLabel:

class DragWidget : public QFrame
{
public:
    explicit DragWidget(QWidget *parent = nullptr);

protected:
    void dragEnterEvent(QDragEnterEvent *event) override;
    void dragMoveEvent(QDragMoveEvent *event) override;
    void dropEvent(QDropEvent *event) override;
    void mousePressEvent(QMouseEvent *event) override;
};

Dado que la clase QLabel proporciona la mayor parte de lo que necesitamos para el icono, sólo necesitamos reimplementar la clase QWidget::mousePressEvent() para proporcionar facilidades de arrastrar y soltar.

Implementación de la clase DragWidget

El constructor DragWidget establece un atributo en el widget que asegura que se borrará cuando se cierre:

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);
}

Para habilitar el arrastre desde el icono, necesitamos actuar sobre un evento de pulsación del ratón. Hacemos esto reimplementando QWidget::mousePressEvent() y estableciendo un objeto QDrag.

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());

Dado que enviaremos datos pixmap para el icono e información sobre el clic del usuario en el widget del icono, construimos un QByteArray y empaquetamos los detalles utilizando un QDataStream.

Por razones de interoperabilidad, las operaciones de arrastrar y soltar describen los datos que contienen utilizando tipos MIME. En Qt, describimos estos datos mediante un objeto QMimeData:

    QMimeData *mimeData = new QMimeData;
    mimeData->setData("application/x-dnditemdata", itemData);

Para ello, elegimos un tipo MIME no oficial y proporcionamos la dirección QByteArray al objeto de datos MIME.

La propia operación de arrastrar y soltar se gestiona mediante un objeto QDrag:

    QDrag *drag = new QDrag(this);
    drag->setMimeData(mimeData);
    drag->setPixmap(pixmap);
    drag->setHotSpot(event->position().toPoint() - child->pos());

Aquí, pasamos los datos al objeto drag, establecemos un pixmap que se mostrará junto al cursor durante la operación, y definimos la posición de un hot spot que sitúa la posición de este pixmap bajo el cursor.

Proyecto de ejemplo @ code.qt.io

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.