Qt Widgets: QPlainTextDocumentLayout::frameBoundingRect()でテキスト配置を自由自在に操る


QPlainTextDocumentLayout::frameBoundingRect() は、QPlainTextDocumentLayout クラスの仮想関数であり、指定されたテキストフレームの境界矩形を取得するために使用されます。この境界矩形は、フレーム内のテキストコンテンツを囲む最小の矩形を表します。

構文

QRectF QPlainTextDocumentLayout::frameBoundingRect(QTextFrame *frame) const;

パラメータ

  • frame: 境界矩形を取得するテキストフレームへのポインタ

戻り値

フレームの境界矩形を表す QRectF オブジェクト

詳細

frameBoundingRect() 関数は、テキストフレーム内のすべての行と段落の境界矩形を考慮して境界矩形を計算します。このため、フレーム内のテキストコンテンツの正確な位置とサイズを知るのに役立ちます。

QTextFrame *frame = layout.document()->rootFrame();
QRectF rect = layout.frameBoundingRect(frame);

// rect.x() はフレームの左端の X 座標を表します
// rect.y() はフレームの左上の Y 座標を表します
// rect.width() はフレームの幅を表します
// rect.height() はフレームの高さを表します
  • QPlainTextDocumentLayout クラスは、QTextDocument オブジェクト内のテキストコンテンツをレイアウトするために使用されます。
  • QTextFrame クラスは、テキストコンテンツをレイアウトするための基本的な要素です。


#include <QApplication>
#include <QPlainTextEdit>
#include <QTextDocument>
#include <QTextFrame>
#include <QPainter>

int main(int argc, char *argv[]) {
  QApplication app(argc, argv);

  QPlainTextEdit editor;
  editor.setPlainText("This is some text.\n\nThis is another line of text.");

  QTextDocument *document = editor.document();
  QPlainTextDocumentLayout *layout = document->layout();

  QTextFrame *frame = layout->document()->rootFrame();
  QRectF rect = layout->frameBoundingRect(frame);

  // フレームの境界矩形を描画する
  QPainter painter(&editor);
  painter.setPen(Qt::red);
  painter.drawRect(rect);

  editor.show();

  return app.exec();
}

このコードを実行すると、次のようになります。

赤い四角形が、テキストフレームの境界矩形を表します。

  1. QApplication オブジェクトを作成します。
  2. QPlainTextEdit ウィジェットを作成し、テキストを設定します。
  3. QTextDocument オブジェクトと QPlainTextDocumentLayout オブジェクトを取得します。
  4. ルートフレームを取得します。
  5. frameBoundingRect() 関数を使用して、フレームの境界矩形を取得します。
  6. QPainter オブジェクトを使用して、境界矩形を描画します。
  7. QPlainTextEdit ウィジェットを表示します。


以下に、いくつかの代替方法とその利点と欠点をご紹介します。

QTextFrame::boundingRect() 関数

この関数は、テキストフレームの境界矩形を取得するために使用できます。QPlainTextDocumentLayout::frameBoundingRect() 関数と同様に、フレーム内のテキストコンテンツの正確な位置とサイズを把握できます。

利点

  • 計算コストが比較的低い
  • シンプルで分かりやすい

欠点

  • フレーム内の装飾やマージンを考慮しない

手動で境界矩形を計算する

フレーム内の各行と段落の境界矩形を個別に計算し、それらを組み合わせて全体の境界矩形を計算することができます。

利点

  • より精度の高い境界矩形を取得できる
  • フレーム内の装飾やマージンを考慮できる

欠点

  • コードが冗長になる
  • 複雑で計算コストが高い

選択の指針

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

  • より精度の高い境界矩形が必要な場合は、手動で境界矩形を計算する必要があります。
  • フレーム内の装飾やマージンを考慮する必要がある場合は、QPlainTextDocumentLayout::frameBoundingRect() 関数を使用するか、手動で境界矩形を計算する必要があります。
  • フレーム内の装飾やマージンを考慮する必要がない場合は、QTextFrame::boundingRect() 関数を使用するのが最も簡単です。
// QTextFrame::boundingRect() 関数を使用する例

QTextFrame *frame = layout.document()->rootFrame();
QRectF rect = frame->boundingRect();

// 手動で境界矩形を計算する例

QRectF rect;
for (QTextBlock block : layout.document()->blocks()) {
  for (QTextLine line : block.textLines()) {
    QRectF lineRect = line.rect();
    rect = rect.united(lineRect);
  }
}
  • 手動で境界矩形を計算する場合は、QTextLine::rect() 関数や QTextBlock::textLines() 関数などの関数を活用できます。
  • QTextFrame::boundingRect() 関数は、Qt Widgets 5.14.0 以降で利用可能です。