このページでは

ドラッグ可能なアイコンの例

「ドラッグ可能なアイコン」の例では、同じアプリケーション内のウィジェット間、および異なるアプリケーション間で、画像データをドラッグ&ドロップする方法を示しています。

ドラッグ&ドロップイベントに応答するアイコンを備えたアプリケーション

ドラッグ&ドロップが使用される多くの状況では、ユーザーは特定のウィジェットからドラッグを開始し、別のウィジェットにペイロードをドロップします。この例では、QLabel をサブクラス化してドラッグソースとして使用するラベルを作成し、それらをコンテナおよびドロップ先として機能するQWidget内に配置します。

さらに、ドラッグ&ドロップ操作が発生した際、画像だけでなく、ユーザーが画像のどこをクリックしたかという情報も送信したいと考えています。これにより、ユーザーはドロップ先の上に画像を正確に配置できるようになります。このレベルの詳細情報を扱うためには、データ用にカスタム 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());

アイコン用のピクマップデータと、アイコンウィジェットでのユーザーのクリックに関する情報を送信するため、QByteArray を構築し、QDataStream を使用して詳細をパッケージ化します。

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

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

この目的のために非公式のMIMEタイプを選択し、そのQByteArray をMIMEデータオブジェクトに提供します。

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

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

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

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