Qt: シーンサイズ変更前の情報を取得!QGraphicsSceneResizeEvent::oldSize()の使い方


QGraphicsSceneResizeEvent::oldSize() は、Qt WidgetsライブラリにおけるQGraphicsSceneクラスのイベント処理に関わる関数の一つです。この関数は、QGraphicsSceneオブジェクトがサイズ変更された際に、変更前のサイズを取得するために使用されます。

詳細

QGraphicsSceneResizeEventクラスは、QGraphicsSceneオブジェクトがサイズ変更された際に発生するイベントを表します。このイベントには、変更後の新しいサイズと変更前の古いサイズに関する情報が含まれています。

QGraphicsSceneResizeEvent::oldSize() 関数は、イベントオブジェクトから古いサイズを取得するために使用されます。この関数は、QSizeF型の値を返します。QSizeF型は、2D空間における幅と高さを表す型です。

以下のコードは、QGraphicsSceneResizeEventイベントを処理し、古いサイズと新しいサイズを出力する例です。

void MyGraphicsScene::resizeEvent(QGraphicsSceneResizeEvent *event)
{
    QSizeF oldSize = event->oldSize();
    QSizeF newSize = event->newSize();

    qDebug() << "Old size:" << oldSize;
    qDebug() << "New size:" << newSize;
}

このコードでは、resizeEvent() メソッドが QGraphicsSceneResizeEvent イベントを受け取ります。このメソッドは、oldSize()newSize() 関数を使用して、古いサイズと新しいサイズを取得します。そして、取得したサイズは qDebug() 関数を使用して出力されます。



例1: サイズ変更前の矩形を描画する

この例では、QGraphicsSceneResizeEvent イベントを処理し、サイズ変更前の矩形を描画します。

#include <QCoreApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QPainter>
#include <QRectF>

class MyGraphicsScene : public QGraphicsScene
{
public:
    MyGraphicsScene(QObject *parent = nullptr) : QGraphicsScene(parent) {}

protected:
    void resizeEvent(QGraphicsSceneResizeEvent *event) override
    {
        QSizeF oldSize = event->oldSize();
        QGraphicsScene::resizeEvent(event);

        // サイズ変更前の矩形を描画
        QRectF oldRect(0, 0, oldSize.width(), oldSize.height());
        QPainter painter(this);
        painter.setPen(Qt::red);
        painter.drawRect(oldRect);
    }
};

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

    MyGraphicsScene scene;
    scene.setSceneRect(QRectF(0, 0, 400, 300));

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

    return app.exec();
}

このコードを実行すると、以下のようになります。

  1. 400 x 300 ピクセルのサイズのシーンが表示されます。
  2. シーンのサイズを変更すると、変更前の矩形が赤い線で描画されます。

例2: サイズ変更前のオブジェクトの位置を更新する

この例では、QGraphicsSceneResizeEvent イベントを処理し、サイズ変更前のオブジェクトの位置を更新します。

#include <QCoreApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsItem>

class MyGraphicsItem : public QGraphicsItem
{
public:
    MyGraphicsItem(const QRectF &rect, QObject *parent = nullptr) : QGraphicsItem(parent)
    {
        setRect(rect);
    }
};

class MyGraphicsScene : public QGraphicsScene
{
public:
    MyGraphicsScene(QObject *parent = nullptr) : QGraphicsScene(parent) {}

protected:
    void resizeEvent(QGraphicsSceneResizeEvent *event) override
    {
        QSizeF oldSize = event->oldSize();
        QGraphicsScene::resizeEvent(event);

        // サイズ変更前のオブジェクトの位置を更新
        MyGraphicsItem *item = findItemByName("myItem");
        if (item) {
            QRectF oldRect = item->sceneRect();
            QRectF newRect(oldRect.x() / oldSize.width() * sceneRect().width(),
                           oldRect.y() / oldSize.height() * sceneRect().height(),
                           oldRect.width(), oldRect.height());
            item->setPos(newRect.topLeft());
        }
    }
};

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

    MyGraphicsScene scene;
    scene.setSceneRect(QRectF(0, 0, 400, 300));

    MyGraphicsItem *item = new MyGraphicsItem(QRectF(100, 100, 50, 50), &scene);
    item->setName("myItem");
    scene.addItem(item);

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

    return app.exec();
}
  1. 400 x 300 ピクセルのサイズのシーンが表示され、その中に青い四角形のオブジェクトが描画されます。
  2. シーンのサイズを変更すると、青い四角形のオブジェクトの位置が、サイズ変更前の位置に比例して更新されます。


以下に、QGraphicsSceneResizeEvent::oldSize() の代替方法をいくつか紹介します。

sceneRect() 関数を使用する

QGraphicsScene::sceneRect() 関数は、シーンの現在の矩形を取得します。この矩形は、シーンが最後にサイズ変更されたときのサイズと同じです。

QRectF oldRect = scene->sceneRect();

この方法は、QGraphicsSceneResizeEvent::oldSize() 関数よりもシンプルですが、シーンが最後にサイズ変更された時点からのみサイズを取得できます。シーンが複数回サイズ変更された場合、この方法は古い情報に基づいてしまう可能性があります。

QGraphicsSceneHistory クラスを使用する

QGraphicsSceneHistory クラスは、シーンの状態履歴を管理するクラスです。このクラスを使用して、シーンの過去の状態にアクセスすることができます。

QGraphicsSceneHistory *history = scene->history();
if (history->canUndo()) {
    QGraphicsSceneState *state = history->undoState();
    QRectF oldRect = state->sceneRect();
}

この方法は、QGraphicsSceneResizeEvent::oldSize() 関数よりも柔軟性がありますが、QGraphicsSceneHistory クラスを使用する必要があるため、コードが複雑になります。

カスタムイベントを使用する

カスタムイベントを使用して、サイズ変更イベントに関する情報を独自に伝達することができます。

class MySizeChangeEvent : public QEvent
{
public:
    MySizeChangeEvent(const QSizeF &oldSize) : QEvent(Type) {
        this->oldSize = oldSize;
    }

    QSizeF oldSize;
};

class MyGraphicsScene : public QGraphicsScene
{
public:
    MyGraphicsScene(QObject *parent = nullptr) : QGraphicsScene(parent) {}

protected:
    void resizeEvent(QGraphicsSceneResizeEvent *event) override
    {
        QSizeF oldSize = event->oldSize();
        QGraphicsScene::resizeEvent(event);

        // カスタムイベントを発行
        MySizeChangeEvent sizeChangeEvent(oldSize);
        QApplication::postEvent(this, &sizeChangeEvent);
    }
};

class MyGraphicsItem : public QGraphicsItem
{
public:
    MyGraphicsItem(const QRectF &rect, QObject *parent = nullptr) : QGraphicsItem(parent) {
        setRect(rect);
    }

protected:
    bool event(QEvent *event) override
    {
        if (event->type() == MySizeChangeEvent::Type) {
            MySizeChangeEvent *sizeChangeEvent = static_cast<MySizeChangeEvent *>(event);

            // サイズ変更前の情報に基づいて処理を行う
            QRectF oldRect = sizeChangeEvent->oldSize;

            return true;
        }

        return QGraphicsItem::event(event);
    }
};

この方法は、QGraphicsSceneResizeEvent::oldSize() 関数よりも柔軟性がありますが、コードが複雑になり、イベント処理ロジックをオブジェクトに分散させる必要があります。

状況に応じた選択

どの代替方法を使用するかは、状況によって異なります。

  • 柔軟性と制御が必要な場合は、カスタムイベントを使用します。
  • 過去のサイズ情報が必要な場合は、QGraphicsSceneHistory クラスを使用します。
  • シンプルで使いやすい方法が必要な場合は、sceneRect() 関数を使用します。
  • 代替方法を使用する場合は、シーンとオブジェクトが適切に連携するようにする必要があります。
  • QGraphicsSceneResizeEvent::oldSize() 関数は、シーンがサイズ変更された際にのみ発生するイベントです。シーンが他の方法で変更された場合、この関数は古い情報を提供しない可能性があります。