【初心者でも安心】Qt GUIプログラミング:QPainter::boundingRect()でバウンディングボックスを操るチュートリアル


QPainter::boundingRect()は、Qt GUIにおける低レベル描画操作を担うQPainterクラスに属するメソッドです。このメソッドは、テキストや図形などの描画対象に対して、その境界となる矩形(バウンディングボックス)を算出します。バウンディングボックスは、描画対象の形状やサイズを把握する上で有用な情報となります。

用途

QPainter::boundingRect()は、様々な場面で活用できます。以下に、代表的な用途をいくつか挙げます。

  • テキスト編集
    テキスト編集において、カーソル位置や選択範囲をバウンディングボックスに基づいて制御することができます。
  • 衝突判定
    複数の描画対象が互いに干渉していないかを判断するために、バウンディングボックスを用いて衝突判定を行うことができます。
  • レイアウト調整
    ウィジェットの配置やサイズ調整において、バウンディングボックスに基づいて最適なレイアウトを計算することができます。
  • 描画領域の制限
    描画対象が指定された領域内に収まるように、バウンディングボックスを用いて描画位置を調整することができます。

使用方法

QPainter::boundingRect()の使用方法は以下の通りです。

QRect QPainter::boundingRect(const QRectF &rect, const QString &text, const QTextFormat &format, Qt::TextOrientation &orientation) const;

このメソッドは、以下の引数を受け取ります。

  • orientation: テキストの方向
  • format: テキストフォーマット
  • text: 描画対象となるテキスト
  • rect: 描画対象が描かれる矩形

メソッドの戻り値は、描画対象のバウンディングボックスを表すQRectオブジェクトです。

以下のコードは、"Hello, World!"というテキストのバウンディングボックスを算出する例です。

QRectF rect(100, 50, 200, 30);
QString text("Hello, World!");
QFont font("Arial", 12);
QTextFormat format;
format.setFont(font);

QPainter painter;
QRect boundingRect = painter.boundingRect(rect, text, format);

qDebug() << boundingRect;

このコードを実行すると、以下の出力が得られます。

QRect(100, 50, 102, 30)

QPainter::boundingRect()は、描画対象の種類によって異なる結果を返す場合があります。例えば、テキストの場合、テキストフォーマットや改行設定によってバウンディングボックスのサイズが変化します。

また、QPainter::boundingRect()は、描画対象の実際の描画結果とは必ずしも一致するわけではありません。これは、描画処理におけるスケーリングや回転などの影響を受けるためです。



QRectF rect(100, 50, 200, 30);
QString text("Hello, World!");
QFont font("Arial", 12);
QTextFormat format;
format.setFont(font);

QPainter painter;
QRect boundingRect = painter.boundingRect(rect, text, format);

qDebug() << boundingRect;
  1. QRectFオブジェクト rect を作成し、描画対象となる矩形を定義します。
  2. 描画対象となるテキスト text を定義します。
  3. QFontオブジェクト font を作成し、テキストのフォントを設定します。
  4. QTextFormatオブジェクト format を作成し、テキストフォーマットを設定します。
  5. QPainterオブジェクト painter を作成します。
  6. painter.boundingRect() メソッドを使用して、recttextformat に基づいてバウンディングボックスを算出します。
  7. 算出されたバウンディングボックスを qDebug() で出力します。
QImage image("image.png");
QRect boundingRect = image.rect();

qDebug() << boundingRect;

このコードは以下の処理を行います。

  1. 画像ファイル "image.png" を読み込み、QImageオブジェクト image に格納します。
  2. image.rect() メソッドを使用して、画像のバウンディングボックスを算出します。
  3. 算出されたバウンディングボックスを qDebug() で出力します。
QPainter painter;
painter.begin(this);

painter.drawRect(100, 50, 150, 100);
painter.drawEllipse(200, 50, 100, 100);
painter.drawLine(300, 50, 300, 150);

QRectF boundingRect = painter.boundingRect();

painter.end();

qDebug() << boundingRect;
  1. QPainterオブジェクト painter を作成し、描画処理を開始します。
  2. 長方形、楕円形、直線を描画します。
  3. painter.boundingRect() メソッドを使用して、描画された図形全体のバウンディングボックスを算出します。
  4. 描画処理を終了します。
  5. 算出されたバウンディングボックスを qDebug() で出力します。


QRectF::adjusted()

QRectF::adjusted() メソッドは、既存のQRectFオブジェクトに対して、指定されたマージン値を追加または削除することで、バウンディングボックスを調整することができます。

QRectF rect(100, 50, 200, 30);
QRectF adjustedRect = rect.adjusted(10, 5, -15, -10);

qDebug() << adjustedRect;

このコードは、rect オブジェクトに対して、左右に10ピクセル、上下に5ピクセルずつマージンを追加します。

QFontMetrics

QFontMetrics クラスは、特定のフォントに対する様々な情報を提供するクラスです。その中には、テキストのバウンディングボックスを算出する機能も含まれています。

QFont font("Arial", 12);
QFontMetrics metrics(font);
QRect boundingRect = metrics.boundingRect(0, 0, 100, 100, Qt::TextSingleLine, "Hello, World!");

qDebug() << boundingRect;

このコードは、"Hello, World!"というテキストのバウンディングボックスを、指定されたフォントとサイズで算出します。

QTextLayout

QTextLayout クラスは、テキストをレイアウトするクラスです。その中には、テキストのバウンディングボックスを算出する機能も含まれています。

QTextLayout layout;
layout.setText("Hello, World!");
QTextOption option;
option.setWrapMode(QTextOption::WordWrap);
layout.setOptions(option);

QRect boundingRect = layout.boundingRect();

qDebug() << boundingRect;

このコードは、"Hello, World!"というテキストを折り返しでレイアウトし、そのバウンディングボックスを算出します。

手動計算

単純な形状の場合、バウンディングボックスを手動で計算することも可能です。

QRectF rect(100, 50, 200, 30);

qreal minX = rect.left();
qreal minY = rect.top();
qreal maxX = rect.right();
qreal maxY = rect.bottom();

QRect boundingRect(minX, minY, maxX - minX, maxY - minY);

qDebug() << boundingRect;

このコードは、rect オブジェクトのバウンディングボックスを、最小X座標、最小Y座標、最大X座標、最大Y座標を用いて手動で計算します。

  • 手動計算
    • 利点: 処理速度が速い。
    • 欠点: コードが複雑になり、バグが発生しやすい。
  • QTextLayout
    • 利点: テキストのレイアウトを考慮したバウンディングボックスを算出できる。
    • 欠点: コードが複雑になる。
  • QFontMetrics
    • 利点: 特定のフォントに対するバウンディングボックスを算出できる。
    • 欠点: テキストのレイアウトを考慮しないため、複雑なテキストのバウンディングボックスを算出するには不向き。
  • QRectF::adjusted()
    • 利点: 既存のQRectFオブジェクトを調整するだけで済むため、簡潔なコードで記述できる。
    • 欠点: テキストや複雑な形状のバウンディングボックスを算出するには不向き。