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()
を使用するのが効率的です。
- 上記