Draggable Icons Beispiel

Das Beispiel für Draggable Icons zeigt, wie man Bilddaten zwischen Widgets in derselben Anwendung und zwischen verschiedenen Anwendungen ziehen und ablegen kann.

In vielen Situationen, in denen Drag & Drop verwendet wird, beginnt der Benutzer mit dem Ziehen von einem bestimmten Widget aus und lässt die Nutzlast auf ein anderes Widget fallen. In diesem Beispiel erstellen wir mit der Unterklasse QLabel Labels, die wir als Drag-Quellen verwenden, und platzieren sie in QWidget, die sowohl als Container als auch als Drop-Sites dienen.

Darüber hinaus wollen wir bei einem Drag&Drop-Vorgang mehr als nur ein Bild senden. Wir wollen auch Informationen darüber senden, wo der Benutzer auf das Bild geklickt hat, damit er es genau auf dem Ablageziel platzieren kann. Dieser Detaillierungsgrad bedeutet, dass wir einen eigenen MIME-Typ für unsere Daten erstellen müssen.

DragWidget-Klassendefinition

Die Icon-Widgets, die wir zur Anzeige von Icons verwenden, sind eine Unterklasse von 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;
};

Da die Klasse QLabel das meiste von dem bereitstellt, was wir für das Icon benötigen, müssen wir nur die Klasse QWidget::mousePressEvent() neu implementieren, um Drag & Drop-Funktionen bereitzustellen.

Implementierung der DragWidget-Klasse

Der DragWidget Konstruktor setzt ein Attribut für das Widget, das sicherstellt, dass es gelöscht wird, wenn es geschlossen wird:

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

Um das Ziehen vom Symbol aus zu ermöglichen, müssen wir auf ein Mausdruckereignis reagieren. Wir tun dies, indem wir QWidget::mousePressEvent() neu implementieren und ein QDrag Objekt einrichten.

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

Da wir Pixmap-Daten für das Icon und Informationen über den Klick des Benutzers im Icon-Widget senden werden, konstruieren wir ein QByteArray und verpacken die Details mit einem QDataStream.

Aus Gründen der Interoperabilität beschreiben Drag&Drop-Operationen die enthaltenen Daten mit MIME-Typen. In Qt beschreiben wir diese Daten mit einem QMimeData Objekt:

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

Wir wählen einen inoffiziellen MIME-Typ für diesen Zweck und liefern die QByteArray an das MIME-Datenobjekt.

Der Drag&Drop-Vorgang selbst wird von einem QDrag -Objekt abgewickelt:

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

Hier übergeben wir die Daten an das Drag-Objekt, setzen eine Pixmap, die während des Vorgangs neben dem Cursor angezeigt wird, und definieren die Position eines Hotspots, der die Position dieser Pixmap unter dem Cursor platziert.

Beispielprojekt @ code.qt.io

© 2025 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.