Qt GUIでアニメーションを作成:QPainter::setTransform()を使ってオブジェクトを滑らかに動かす方法


構文

void QPainter::setTransform(const QTransform &transform);

引数

  • transform: 適用する変換を表す QTransform オブジェクト

戻り値

なし

詳細

QPainter::setTransform() メソッドは、QPainter オブジェクトの現在の変換マトリックスを指定された QTransform オブジェクトで置き換えます。この新しい変換マトリックスは、その後のすべての描画操作に適用されます。

変換マトリックスは、6 つの値で構成された 3x3 行列で表されます。これらの値は次のとおりです。

  • dy: 垂直方向のオフセット
  • dx: 水平方向のオフセット
  • m22: 縦方向のスケーリング係数
  • m21: 縦方向のせん断係数
  • m12: 横方向のせん断係数
  • m11: 横方向のスケーリング係数

次のコードは、四角形を 45 度回転する方法を示しています。

QPainter painter(this);
painter.setPen(Qt::red);
painter.drawRect(0, 0, 100, 100);

QTransform transform;
transform.rotate(45);
painter.setTransform(transform);

painter.drawRect(150, 0, 100, 100);

このコードは、次の出力を生成します。

最初の四角形は回転せず、2 番目の四角形は 45 度回転します。

注意事項

QPainter::setTransform() メソッドを使用する前に、現在の変換マトリックスを保存しておくことが重要です。これは、QPainter::save() メソッドを使用して行うことができます。描画操作が完了したら、QPainter::restore() メソッドを使用して元の変換マトリックスを復元する必要があります。

QPainter::setTransform() メソッドは、さまざまな効果を作成するために使用できます。次に、いくつかの例を示します。

  • オブジェクトをせん断するには、shear() メソッドを使用します。
  • オブジェクトを移動するには、translate() メソッドを使用します。
  • オブジェクトを回転するには、rotate() メソッドを使用します。
  • オブジェクトをスケーリングするには、scale() メソッドを使用します。


四角形を回転させる

この例では、四角形を 45 度回転させます。

#include <QApplication>
#include <QWidget>
#include <QPainter>

class ExampleWidget : public QWidget
{
public:
    ExampleWidget()
    {
        setWindowTitle("回転する四角形");
        setFixedSize(250, 250);
    }

protected:
    void paintEvent(QPaintEvent *event) override
    {
        QPainter painter(this);

        // 赤色のペンを設定
        painter.setPen(Qt::red);

        // 最初の四角形を描画
        painter.drawRect(10, 10, 100, 100);

        // 回転変換を作成
        QTransform transform;
        transform.rotate(45);

        // 変換をペインターに設定
        painter.setTransform(transform);

        // 2 番目の四角形を描画
        painter.drawRect(150, 10, 100, 100);
    }
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    ExampleWidget widget;
    widget.show();
    return app.exec();
}

このコードを実行すると、次の出力が表示されます。

三角形をスケーリングする

この例では、三角形を 2 倍にスケーリングします。

#include <QApplication>
#include <QWidget>
#include <QPainter>

class ExampleWidget : public QWidget
{
public:
    ExampleWidget()
    {
        setWindowTitle("スケーリングされた三角形");
        setFixedSize(250, 250);
    }

protected:
    void paintEvent(QPaintEvent *event) override
    {
        QPainter painter(this);

        // 緑色のペンを設定
        painter.setPen(Qt::green);

        // 最初の三角形を描画
        QPolygon points;
        points << QPoint(50, 100);
        points << QPoint(150, 50);
        points << QPoint(100, 200);
        painter.drawPolygon(points);

        // スケーリング変換を作成
        QTransform transform;
        transform.scale(2, 2);

        // 変換をペインターに設定
        painter.setTransform(transform);

        // 2 番目の三角形を描画
        painter.drawPolygon(points);
    }
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    ExampleWidget widget;
    widget.show();
    return app.exec();
}

最初の三角形はスケーリングされず、2 番目の三角形は 2 倍にスケーリングされます。

この例では、楕円を (50, 50) の位置に移動します。

#include <QApplication>
#include <QWidget>
#include <QPainter>

class ExampleWidget : public QWidget
{
public:
    ExampleWidget()
    {
        setWindowTitle("移動された楕円");
        setFixedSize(250, 250);
    }

protected:
    void paintEvent(QPaintEvent *event) override
    {
        QPainter painter(this);

        // 青色のペンを設定
        painter.setPen(Qt::blue);

        // 最初の楕円を描画
        painter.drawEllipse(75, 75, 100, 50);

        // 移動変換を作成
        QTransform transform;
        transform.translate(50, 50);

        // 変換をペインターに設定
        painter.setTransform(transform);

        // 2 番目の楕円を描画
        painter.drawEllipse(75, 75, 100, 50);
    }
};

int main(int


しかし、状況によっては QPainter::setTransform() メソッドを使用するよりも優れた代替方法があります。以下に、いくつかの代替方法と、それぞれを使用する際の利点と欠点について説明します。

QPainter::setRenderHint(QPainter::RenderHint::HighQualityAntialiasing)

このヒントを有効にすると、QPainter がアンチエイリアシングを使用して描画を滑らかにします。これは、特に斜めの線や曲線をレンダリングする場合に役立ちます。

利点:

  • コードが簡潔になる
  • アンチエイリアシングを使用して描画を滑らかにする

欠点:

  • パフォーマンスが低下する可能性がある

QPainter::setRenderHint(QPainter::RenderHint::Antialiasing)

このヒントは、QPainter::setRenderHint(QPainter::RenderHint::HighQualityAntialiasing) に似ていますが、パフォーマンスが向上します。

  • QPainter::setRenderHint(QPainter::RenderHint::HighQualityAntialiasing) よりもパフォーマンスが向上する
  • アンチエイリアシングを使用して描画を滑らかにする
  • QPainter::setRenderHint(QPainter::RenderHint::HighQualityAntialiasing) ほど滑らかにない可能性がある

QGraphicsView を使用する

QGraphicsView は、2D グラフィックスをレンダリングするためのフレームワークです。QGraphicsView を使用すると、QPainter::setTransform() メソッドを使用せずにオブジェクトを回転、スケーリング、移動できます。

  • ズームやパンなどの機能を簡単に追加できる
  • QPainter::setTransform() メソッドを使用するよりもコードがシンプルになる可能性がある
  • QPainter ほど柔軟ではない

QGLWidget を使用する

QGLWidget は、OpenGL を使用して 2D グラフィックスをレンダリングするためのウィジェットです。QGLWidget を使用すると、QPainter::setTransform() メソッドを使用するよりも高度な変換を適用できます。

  • 非常に高度な変換を適用できる
  • パフォーマンスが低下する可能性がある
  • 複雑で習得するのが難しい

カスタム描画関数を使用する

独自の描画関数を作成して、必要な変換を適用することもできます。これは、複雑な変換が必要な場合や、QPainter または QGraphicsView で提供される機能では十分ではない場合に役立ちます。

  • 必要な変換を正確に制御できる
  • 複雑で時間のかかる場合がある

QPainter::setTransform() メソッドは、2D 変換を QPainter オブジェクトに適用するための汎用的なツールですが、状況によっては代替方法の方が適している場合があります。上記の代替方法を検討し、ニーズに合ったものを選択してください。