Qt Widgets ドラッグアンドドロップの極意:QGraphicsSceneDragDropEvent::dropAction()を使いこなすためのヒント


QGraphicsSceneDragDropEvent::dropAction()は、Qt Widgetsにおけるドラッグアンドドロップ操作で実行されるアクションを取得するための関数です。ドラッグアンドドロップ操作において、ドロップされたアイテムに対してどのような処理を行うかを決定する際に重要な役割を果たします。

機能

この関数は、以下の情報を返します。

  • Qt::DropAction: ドロップアクションを表す列挙値。可能な値は以下の通りです。
    • Qt::CopyAction: ドラッグされたアイテムのコピーをドロップ先に作成します。
    • Qt::MoveAction: ドラッグされたアイテムをドロップ先に移動します。
    • Qt::LinkAction: ドラッグされたアイテムへのリンクをドロップ先に作成します。
    • Qt::IgnoreAction: ドロップアクションは実行されません。
    • Qt::ActionMask: すべてのドロップアクションを表します。

使用方法

QGraphicsSceneDragDropEvent::dropAction()は以下の例のように使用できます。

void MyGraphicsItem::dragDropEvent(QGraphicsSceneDragDropEvent *event)
{
    if (event->dropAction() == Qt::MoveAction) {
        // ドラッグされたアイテムを移動する処理
    } else if (event->dropAction() == Qt::CopyAction) {
        // ドラッグされたアイテムのコピーを作成する処理
    } else {
        // その他の処理
    }
}
  • QGraphicsSceneDragDropEvent::setDropAction()を使用して、ドロップアクションを設定することもできます。
  • ドロップアクションは、ドラッグソースとドロップ先の設定によって異なる場合があります。
  • QGraphicsSceneDragDropEvent::dropAction()は、ドラッグアンドドロップ操作が完了する前に呼び出されます。

プログラミング例

以下の例は、QGraphicsSceneDragDropEvent::dropAction()を使用して、ドラッグされたアイテムを移動またはコピーするデモです。

#include <QGraphicsScene>
#include <QGraphicsItem>
#include <QGraphicsView>
#include <QApplication>

class MyGraphicsItem : public QGraphicsItem
{
public:
    MyGraphicsItem(QGraphicsItem *parent = nullptr);

protected:
    void dragDropEvent(QGraphicsSceneDragDropEvent *event) override;
};

MyGraphicsItem::MyGraphicsItem(QGraphicsItem *parent)
    : QGraphicsItem(parent)
{
    setFlag(QGraphicsItem::ItemIsMovable);
    setFlag(QGraphicsItem::ItemAcceptsDrops);
}

void MyGraphicsItem::dragDropEvent(QGraphicsSceneDragDropEvent *event)
{
    if (event->dropAction() == Qt::MoveAction) {
        setPos(event->pos());
    } else if (event->dropAction() == Qt::CopyAction) {
        QGraphicsItem *newItem = clone();
        newItem->setPos(event->pos());
        scene()->addItem(newItem);
    }
}

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QGraphicsScene scene;
    MyGraphicsItem *item = new MyGraphicsItem(&scene);
    item->setPos(100, 100);

    QGraphicsView view(&scene);
    view.show();

    return app.exec();
}

この例では、MyGraphicsItemクラスは、ドラッグされたアイテムを移動またはコピーできるグラフィックアイテムです。dragDropEvent()メソッドは、QGraphicsSceneDragDropEvent::dropAction()を使用して、ドロップアクションを取得し、それに応じてアイテムを処理します。



ドラッグされたアイテムを移動する

#include <QGraphicsScene>
#include <QGraphicsItem>
#include <QGraphicsView>
#include <QApplication>

class MyGraphicsItem : public QGraphicsItem
{
public:
    MyGraphicsItem(QGraphicsItem *parent = nullptr);

protected:
    void dragDropEvent(QGraphicsSceneDragDropEvent *event) override;
};

MyGraphicsItem::MyGraphicsItem(QGraphicsItem *parent)
    : QGraphicsItem(parent)
{
    setFlag(QGraphicsItem::ItemIsMovable);
    setFlag(QGraphicsItem::ItemAcceptsDrops);
}

void MyGraphicsItem::dragDropEvent(QGraphicsSceneDragDropEvent *event)
{
    if (event->dropAction() == Qt::MoveAction) {
        setPos(event->pos());
    }
}

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QGraphicsScene scene;
    MyGraphicsItem *item = new MyGraphicsItem(&scene);
    item->setPos(100, 100);

    QGraphicsView view(&scene);
    view.show();

    return app.exec();
}

ドラッグされたアイテムのコピーを作成する

#include <QGraphicsScene>
#include <QGraphicsItem>
#include <QGraphicsView>
#include <QApplication>

class MyGraphicsItem : public QGraphicsItem
{
public:
    MyGraphicsItem(QGraphicsItem *parent = nullptr);

protected:
    void dragDropEvent(QGraphicsSceneDragDropEvent *event) override;
};

MyGraphicsItem::MyGraphicsItem(QGraphicsItem *parent)
    : QGraphicsItem(parent)
{
    setFlag(QGraphicsItem::ItemIsMovable);
    setFlag(QGraphicsItem::ItemAcceptsDrops);
}

void MyGraphicsItem::dragDropEvent(QGraphicsSceneDragDropEvent *event)
{
    if (event->dropAction() == Qt::CopyAction) {
        QGraphicsItem *newItem = clone();
        newItem->setPos(event->pos());
        scene()->addItem(newItem);
    }
}

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QGraphicsScene scene;
    MyGraphicsItem *item = new MyGraphicsItem(&scene);
    item->setPos(100, 100);

    QGraphicsView view(&scene);
    view.show();

    return app.exec();
}

このコードは、ドラッグされたアイテムのコピーを作成するものです。dragDropEvent()メソッド内で、QGraphicsSceneDragDropEvent::dropAction()を使用してドロップアクションを取得し、それが Qt::CopyAction である場合は、clone()を使用してアイテムのコピーを作成し、setPos()を使用してコピーの位置をドロップ先の位置に設定します。

#include <QGraphicsScene>
#include <QGraphicsItem>
#include <QGraphicsView>
#include <QApplication>

class MyGraphicsItem : public QGraphicsItem
{
public:
    MyGraphicsItem(QGraphicsItem *parent = nullptr);

protected:
    void dragDropEvent(QGraphicsSceneDragDropEvent *event) override;
};

MyGraphicsItem::MyGraphicsItem(QGraphicsItem *parent)
    : QGraphicsItem(parent)
{
    setFlag(QGraphicsItem::ItemIsMovable);
    setFlag(QGraphicsItem::ItemAcceptsDrops);
}

void MyGraphicsItem::dragDropEvent(QGraphicsSceneDragDropEvent *event)
{
    if (event->dropAction() == Qt::LinkAction) {
        // ドロップされたアイテムへのリンクを作成する処理
    }
}

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QGraphicsScene scene;
    MyGraphicsItem *item = new MyGraphicsItem(&scene);
    item->setPos(100, 100);

    QGraphicsView view(&scene);


代替方法

  1. QGraphicsSceneDragDropEvent::mimeData()

QGraphicsSceneDragDropEvent::mimeData()は、ドラッグアンドドロップ操作で転送されるMIMEデータを取得するための関数です。このMIMEデータを使用して、ドロップされたアイテムの種類を判断することができます。

void MyGraphicsItem::dragDropEvent(QGraphicsSceneDragDropEvent *event)
{
    if (event->mimeData()->hasFormat("application/x-qgraphics-item")) {
        // ドロップされたアイテムはQGraphicsItemである
    } else {
        // ドロップされたアイテムはQGraphicsItemではない
    }
}
  1. QGraphicsSceneDragDropEvent::source()

QGraphicsSceneDragDropEvent::source()は、ドラッグされたアイテムのソースを取得するための関数です。このソースを使用して、ドロップされたアイテムの種類を判断することができます。

void MyGraphicsItem::dragDropEvent(QGraphicsSceneDragDropEvent *event)
{
    if (event->source()->type() == QGraphicsItem::Type) {
        // ドロップされたアイテムはQGraphicsItemである
    } else {
        // ドロップされたアイテムはQGraphicsItemではない
    }
}

注意事項

  • 状況に応じて、適切な方法を選択する必要があります。
  • しかし、QGraphicsSceneDragDropEvent::dropAction()の方が、より簡潔で分かりやすいコードになる場合もあります。
  • 上記の代替方法は、QGraphicsSceneDragDropEvent::dropAction()よりも汎用性が高い場合があります。
  • ドロップされたアイテムとドロップ先の関係を分析する
  • ドロップされたアイテムの位置を分析する
  • ドロップされたアイテムの形状やサイズを分析する

これらの方法は、状況によっては有効な場合があります。