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

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

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

プロジェクト例 @ code.qt.io

©2024 The Qt Company Ltd. ここに含まれるドキュメントの著作権は、それぞれの所有者に帰属します。 ここで提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。