Qt GUIプログラミングの高度なテクニック:QGraphicsSceneMoveEvent::newPos()を使ってカスタムイベントを作成


QGraphicsSceneMoveEvent::newPos()は、Qt Widgetsライブラリにおける重要な機能の一つであり、グラフィカルユーザインターフェース(GUI)上でアイテムが移動された際にその新しい位置を取得するために使用されます。この関数は、QGraphicsSceneMoveEventクラスに属しており、アイテムが移動されたことを示すイベントを処理します。

機能

QGraphicsSceneMoveEvent::newPos()関数は、移動されたアイテムの新しい位置をQPointF型で返します。QPointF型は、2D空間における点の位置を表すデータ型です。この関数は、アイテムが移動された際の新しいX座標とY座標をそれぞれ取得することができます。

使用方法

QGraphicsSceneMoveEvent::newPos()関数は、QGraphicsItemクラスから派生したカスタムアイテムクラス内で、itemChange()仮想関数をオーバーライドすることで使用することができます。itemChange()関数は、アイテムの状態が変化した際に呼び出されるものであり、QGraphicsSceneMoveEvent型のイベントが渡されます。

以下のコード例は、QGraphicsSceneMoveEvent::newPos()関数を使用して、移動されたアイテムの新しい位置をログに出力する方法を示しています。

class MyItem : public QGraphicsItem
{
public:
    void itemChange(QGraphicsItem::ItemChange change) override
    {
        if (change == ItemPositionChange) {
            QGraphicsSceneMoveEvent *event = static_cast<QGraphicsSceneMoveEvent *>(event);
            QPointF newPos = event->newPos();
            qDebug() << "New position: " << newPos;
        }
    }
};

注意点

QGraphicsSceneMoveEvent::newPos()関数は、アイテムが移動された直後にのみ呼び出されます。アイテムが移動後に位置を変更しても、この関数は新しい位置を返しません。



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

class MyItem : public QGraphicsItem
{
public:
    MyItem()
    {
        setFlag(QGraphicsItem::ItemIsMovable);
    }

    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
    {
        painter->setBrush(Qt::red);
        painter->drawRect(-50, -50, 100, 100);
    }

    void itemChange(QGraphicsItem::ItemChange change) override
    {
        if (change == ItemPositionChange) {
            QGraphicsSceneMoveEvent *event = static_cast<QGraphicsSceneMoveEvent *>(event);
            QPointF newPos = event->newPos();
            qDebug() << "New position: " << newPos;
        }
    }
};

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

    QGraphicsScene scene;
    MyItem *item = new MyItem;
    item->setPos(100, 100);
    scene.addItem(item);

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

    return app.exec();
}

このコードを実行すると、赤い四角形が画面に表示されます。四角形をドラッグすると、四角形が移動された際の新しい位置がコンソールに出力されます。



  • アイテムが移動後に位置を変更しても、新しい位置を返しません。
  • アイテムが移動された直後にのみ呼び出されます。

これらの制限を克服するために、QGraphicsSceneMoveEvent::newPos()の代替方法をいくつか紹介します。

QGraphicsItem::pos()関数を使用する

QGraphicsItem::pos()関数は、アイテムの現在位置をQPointF型で返します。この関数は、アイテムが移動された後でも、常に新しい位置を返します。

class MyItem : public QGraphicsItem
{
public:
    void itemChange(QGraphicsItem::ItemChange change) override
    {
        if (change == ItemPositionChange) {
            QPointF newPos = pos();
            qDebug() << "New position: " << newPos;
        }
    }
};

QGraphicsItem::scenePos()関数を使用する

QGraphicsItem::scenePos()関数は、アイテムの現在位置をシーン座標系におけるQPointF型で返します。この関数は、アイテムが別のアイテムの子アイテムである場合でも、常に新しい位置を返します。

class MyItem : public QGraphicsItem
{
public:
    void itemChange(QGraphicsItem::ItemChange change) override
    {
        if (change == ItemPositionChange) {
            QPointF newPos = scenePos();
            qDebug() << "New position: " << newPos;
        }
    }
};

QGraphicsItem::transform()関数を使用する

QGraphicsItem::transform()関数は、アイテムの現在の変換行列を返します。この変換行列を使用して、アイテムの新しい位置を計算することができます。

class MyItem : public QGraphicsItem
{
public:
    void itemChange(QGraphicsItem::ItemChange change) override
    {
        if (change == ItemPositionChange) {
            QPointF newPos = transform().map(QPointF(0, 0));
            qDebug() << "New position: " << newPos;
        }
    }
};

QGraphicsScene::mouseMoveEvent()シグナルを使用する

QGraphicsScene::mouseMoveEvent()シグナルは、マウスがシーン上で移動された際に送信されます。このシグナルハンドラ内で、マウスカーソルの現在位置を取得して、アイテムの新しい位置を計算することができます。

void MyScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    QPointF newPos = event->scenePos();
    // アイテムの新しい位置を計算する

    qDebug() << "New position: " << newPos;
}

QGraphicsSceneMoveEvent::newPos()は、アイテムが移動された際の新しい位置を取得する簡単な方法ですが、いくつかの制限があります。これらの制限を克服するために、上記の代替方法を使用することができます。