Qt GUIにおけるブラシ描画の極意:QBrush::transform()で実現できるテクニック


使用方法

void QBrush::setTransform(const QTransform &matrix);

このメソッドには、QTransformオブジェクトを唯一の引数として渡します。QTransformオブジェクトは、2D変換を表す行列をカプセル化しており、以下の操作を定義できます。

  • シアー
  • 平行移動
  • 回転
  • スケーリング

QBrush brush(Qt::red, Qt::TexturePattern);

// テクスチャ画像を2倍に拡大する
QTransform transform;
transform.scale(2, 2);
brush.setTransform(transform);

// ペインタにブラシを設定して、矩形を描画する
QPainter painter(widget);
painter.setBrush(brush);
painter.drawRect(0, 0, 100, 100);

この例では、赤いテクスチャ画像を2倍に拡大して矩形を描画します。

  • QBrush::transform()と組み合わせて使用できる他のメソッドとして、QBrush::matrix()QBrush::resetTransform()があります。
  • QBrush::transform()は、ブラシのコピーを作成し、そのコピーにのみ変換行列を適用します。元のブラシは変更されません。
  • QBrush::transform()は、ブラシのスタイルがQt::NoBrushの場合には何の効果もありません。
  • 上記の解説は、Qt 6.xを対象としています。古いバージョンのQtでは、機能やAPIが異なる場合があります。


テクスチャ画像を回転させる

QBrush brush(QImage("texture.png"), Qt::TexturePattern);

// テクスチャ画像を45度回転する
QTransform transform;
transform.rotate(45);
brush.setTransform(transform);

// ペインタにブラシを設定して、矩形を描画する
QPainter painter(widget);
painter.setBrush(brush);
painter.drawRect(0, 0, 100, 100);

テクスチャ画像を平行移動してスケーリングする

QBrush brush(QImage("texture.png"), Qt::TexturePattern);

// テクスチャ画像を(50, 50)だけ平行移動し、2倍に拡大する
QTransform transform;
transform.translate(50, 50);
transform.scale(2, 2);
brush.setTransform(transform);

// ペインタにブラシを設定して、矩形を描画する
QPainter painter(widget);
painter.setBrush(brush);
painter.drawRect(0, 0, 100, 100);

この例では、"texture.png"というテクスチャ画像を(50, 50)だけ平行移動し、2倍に拡大して矩形を描画します。

複数の変換を組み合わせて適用する

QBrush brush(QImage("texture.png"), Qt::TexturePattern);

// テクスチャ画像を(50, 50)だけ平行移動し、45度回転し、2倍に拡大する
QTransform transform;
transform.translate(50, 50);
transform.rotate(45);
transform.scale(2, 2);
brush.setTransform(transform);

// ペインタにブラシを設定して、矩形を描画する
QPainter painter(widget);
painter.setBrush(brush);
painter.drawRect(0, 0, 100, 100);

この例では、"texture.png"というテクスチャ画像を(50, 50)だけ平行移動し、45度回転し、2倍に拡大して矩形を描画します。

QBrush brush(Qt::red, Qt::TexturePattern);

// 独自の変換行列を作成する
QTransform transform;
transform.setMatrix(2, 0, 0, 2, 50, 50); // 2倍に拡大し、(50, 50)だけ平行移動する
brush.setTransform(transform);

// ペインタにブラシを設定して、矩形を描画する
QPainter painter(widget);
painter.setBrush(brush);
painter.drawRect(0, 0, 100, 100);


QPainter::setRenderHint(QPainter::RenderHint::TransformOriginPoint)

このRenderHintを有効にすることで、ブラシの描画時に原点を指定できるようになります。原点を変更することで、ブラシの位置や回転を調整できます。

QBrush brush(Qt::red);

// ペインタにブラシを設定する
QPainter painter(widget);
painter.setBrush(brush);

// 原点を(50, 50)に設定し、矩形を描画する
painter.setRenderHint(QPainter::RenderHint::TransformOriginPoint);
painter.translate(50, 50);
painter.drawRect(0, 0, 100, 100);

この例では、赤いブラシを(50, 50)の位置に描画します。

QPainter::translate(), QPainter::rotate(), QPainter::scale()

これらのメソッドを使用して、ブラシを描画する前にペインタを直接変換できます。

QBrush brush(Qt::red);

// ペインタにブラシを設定する
QPainter painter(widget);
painter.setBrush(brush);

// ペインタを(50, 50)だけ平行移動し、45度回転し、2倍に拡大する
painter.translate(50, 50);
painter.rotate(45);
painter.scale(2, 2);
painter.drawRect(0, 0, 100, 100);

この例では、赤いブラシを(50, 50)の位置に描画し、45度回転し、2倍に拡大します。

QGraphicsItem::setTransform()

QGraphicsItemサブクラスを使用している場合は、setTransform()メソッドを使用してアイテム自体を直接変換できます。これにより、アイテム内のすべてのブラシも変換されます。

class MyItem : public QGraphicsItem
{
public:
    MyItem()
    {
        setBrush(Qt::red);
    }

protected:
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
    {
        painter->drawRect(boundingRect());
    }
};

int main()
{
    QGraphicsScene scene;
    MyItem *item = new MyItem;
    scene.addItem(item);

    // アイテムを(50, 50)だけ平行移動し、45度回転し、2倍に拡大する
    item->setTransform(QTransform().translate(50, 50).rotate(45).scale(2, 2));

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

    return app.exec();
}

この例では、MyItemというアイテムを作成し、(50, 50)の位置に描画し、45度回転し、2倍に拡大します。

カスタム描画関数

ブラシの描画を完全に制御したい場合は、カスタム描画関数を作成して、ブラシの描画ロジックを直接実装できます。

class MyBrush : public QBrush
{
public:
    void paint(QPainter *painter, const QRect &rect) override
    {
        // ブラシの描画ロジックをここに記述
    }
};

int main()
{
    MyBrush brush(Qt::red);

    // ペインタにブラシを設定する
    QPainter painter(widget);
    painter.setBrush(brush);

    // 矩形を描画する
    painter.drawRect(0, 0, 100, 100);
}

この例では、MyBrushというカスタムブラシを作成し、矩形を描画します。

選択の指針

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

  • ブラシの描画を完全に制御したい場合は、カスタム描画関数を作成します。
  • アイテム内のすべてのブラシに同じ変換を適用したい場合は、QGraphicsItem::setTransform()を使用します。
  • 単純な変換を行う場合は、QPainter::setRenderHint(QPainter::RenderHint::TransformOriginPoint)またはQPainter::translate(), QPainter::rotate(), QPainter::scale()を使用するのが効率的です。
  • 上記