QGraphicsViewのスケールを取得する方法


はじめに

こんばんは、Qt Advent Calendar 2019 の 24日目の記事です。
ケーキを作ってたら少し遅刻してしまいました。

QGraphicsView内の移動、拡大縮小、回転する時の基本的な情報

QGraphicsViewはQTransformを使うことでビューの移動や拡大縮小、回転などか行えます。

以下がQTransformに含まれる3*3のマトリクスの図です。

m31( dx )とm32( dy )要素は、水平方向と垂直方向の平行移動を指定します。m11とm22要素は、水平方向と垂直方向のスケーリングを指定します。 m21およびm12要素は、水平および垂直のせん断を指定します。そして最後に、 m13とm23要素は水平投影と垂直投影を指定し、追加の投影係数としてm33を指定します。

スケールを取得する方法(不十分)

単純なQGraphicsViewの場合、次のコードで現在のQGraphicsViewのスケールを取得することができます。

    QTransform trans = this->transform();
    qreal xScale = trans.m11();
    qreal yScale = trans.m22();

また次のコードは、QTransformを使用してビューの移動と拡大、回転を行った例です。

    QGraphicsView* view = new QGraphicsView(this);
    setCentralWidget(view);
    QGraphicsScene* scene = new QGraphicsScene(this);
    view->setScene(scene);

    qreal x = 50.0;
    qreal y = 50.0;
    qreal angle = 45.0;
    qreal xScale = 2.0;
    qreal yScale = 2.0;

    double theta = M_PI/180 * angle;
    double sinTheta = sin(theta);
    double cosTheta = cos(theta);

    QTransform translationTransform(1, 0, 0, 1, x, y);
    QTransform rotationTransform(cosTheta, sinTheta, -sinTheta, cosTheta, 0, 0); // 回転!
    QTransform scalingTransform(xScale, 0, 0, yScale, 0, 0);                     // 拡大!
    transform = scalingTransform * rotationTransform * translationTransform;
    view->setTransform(transform);

回転と拡大の両方でm11とm22の両方の要素を使用しているのがわかります。
最初に示したコードでは、回転したビューで正しい値を取得することができません。

スケールを取得する方法

回転に左右されない現在のQGraphicsViewのスケールの取得方法です。

    QTransform trans = this->transform();
    qreal xScale = qSqrt(qPow(trans.m11(), 2) + qPow(trans.m12(), 2));
    qreal yScale = qSqrt(qPow(trans.m21(), 2) + qPow(trans.m22(), 2));

おわりに

おやすみなさい。