ドラッガブル・アイコンの例

Draggable Icons の例では、同じアプリケーション内のウィジェット間や、異なるアプリケーション間で画像データをドラッグ・アンド・ドロップする方法を示します。

ドラッグ&ドロップが使用される多くの状況では、ユーザは特定のウィジェットからドラッグを開始し、ペイロードを別のウィジェットにドロップします。この例では、QLabel をサブクラス化して、ドラッグ・ソースとして使用するラベルを作成し、コンテナとドロップ・サイトの両方の役割を果たすQWidgets 内に配置しています。

さらに、ドラッグ・アンド・ドロップ操作が発生したときに送信したいのは、画像だけではありません。また、ユーザが画像のどこをクリックしたかという情報も送信したいので、ユーザは画像をドロップターゲットに正確に配置することができます。このレベルの詳細は、データ用にカスタムMIMEタイプを作成する必要があることを意味します。

DragWidgetクラスの定義

アイコンを表示するために使用するアイコンウィジェットは、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;
};

アイコンに必要なほとんどの機能はQLabel クラスが提供しているので、ドラッグ・アンド・ドロップ機能を提供するためにQWidget::mousePressEvent() を再実装するだけでよい。

DragWidgetクラスの実装

DragWidget コンストラクタは、ウィジェットが閉じられたときに確実に削除されるように、ウィジェットに属性を設定します:

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

アイコンからドラッグできるようにするには、マウス押下イベントに対応する必要があります。そのためには、QWidget::mousePressEvent ()を再実装し、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());

アイコンのpixmapデータと、アイコン・ウィジェットのユーザーのクリックに関する情報を送信するので、QByteArray を作成し、QDataStream を使用して詳細をパッケージ化します。

相互運用性を高めるために、ドラッグ&ドロップ操作では、MIME タイプを使用して含まれるデータを記述します。Qt では、このデータをQMimeData オブジェクトを使って記述します:

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

この目的のために非公式なMIMEタイプを選択し、MIMEデータ・オブジェクトにQByteArray

ドラッグ&ドロップの操作自体は、QDrag オブジェクトによって処理されます:

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

ここでは、ドラッグ・オブジェクトにデータを渡し、操作中にカーソルの横に表示されるピクセルマップを設定し、このピクセルマップの位置をカーソルの下に置くホットスポットの位置を定義する。

プロジェクト例 @ 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.