【実践編】QFontMetricsF::tightBoundingRect() を駆使して、Qt GUI アプリのテキストレイアウトを自由自在に


QFontMetricsFクラスは、フォントに関する情報を提供するクラスです。フォントサイズ、行高、文字幅、字間などの情報に加え、テキストレイアウトに必要な様々な情報を取得することができます。QFontMetricsF::tightBoundingRect()関数は、このQFontMetricsFクラスに属する関数の一つです。

QFontMetricsF::tightBoundingRect()関数の役割

QFontMetricsF::tightBoundingRect()関数は、指定されたテキスト文字列の境界矩形を計算します。境界矩形とは、テキスト文字列を完全に囲む最小限の矩形を指します。この矩形の情報は、テキストレイアウトや描画などの処理において、テキストが占めるスペースを正確に把握するために重要です。

QFontMetricsF::tightBoundingRect()関数の引数

QFontMetricsF::tightBoundingRect()関数は、以下の引数を受け取ります。

  • text: 境界矩形を計算する対象となるテキスト文字列

QFontMetricsF::tightBoundingRect()関数の戻り値

QFontMetricsF::tightBoundingRect()関数は、計算された境界矩形をQRectF型で返します。QRectF型は、浮動小数点数の座標値を使用して矩形を定義するデータ型です。

QFontMetricsF::tightBoundingRect()関数の例

QFontMetricsF fontMetrics(font);
QRectF boundingRect = fontMetrics.tightBoundingRect("Hello, World!");

// boundingRect.x() はテキストの左端の X 座標を取得
// boundingRect.y() はテキストの上端の Y 座標を取得
// boundingRect.width() はテキストの幅を取得
// boundingRect.height() はテキストの高さ

上記の例では、"Hello, World!"というテキスト文字列の境界矩形を計算し、その情報に基づいてテキストの位置やサイズを調整しています。

QFontMetricsF::tightBoundingRect()関数の利点

QFontMetricsF::tightBoundingRect()関数は、以下の利点があります。

  • テキストの位置やサイズの調整
  • テキストが占めるスペースの正確な把握
  • テキストレイアウトや描画処理の効率化

QFontMetricsF::tightBoundingRect()関数の注意点

QFontMetricsF::tightBoundingRect()関数は、以下の点に注意する必要があります。

  • 境界矩形は、テキスト描画に使用される実際の描画領域とは異なる場合があります。
  • 境界矩形は、テキストの形状やフォント設定によって異なる可能性があります。


例1:テキストの位置とサイズを調整する

QFont font("Arial", 12);
QFontMetricsF fontMetrics(font);
QString text = "Hello, World!";

QRectF boundingRect = fontMetrics.tightBoundingRect(text);

QPainter painter(widget);
painter.setFont(font);

painter.drawText(boundingRect.topLeft(), Qt::AlignLeft | Qt::AlignTop, text);

このコードでは、"Hello, World!"というテキスト文字列の境界矩形を計算し、その情報に基づいてテキストの位置とサイズを調整しています。テキストは左揃え上揃えで描画されます。

例2:テキストがウィジェット内に収まるようにサイズを調整する

QFont font("Arial", 12);
QFontMetricsF fontMetrics(font);
QString text = "Hello, World! This is a very long text.";

QWidget *widget = new QWidget(this);
widget->resize(200, 100);

QRectF boundingRect = fontMetrics.tightBoundingRect(text);

while (boundingRect.width() > widget->width() || boundingRect.height() > widget->height()) {
    font.setPointSize(font.pointSize() - 1);
    fontMetrics = QFontMetricsF(font);
    boundingRect = fontMetrics.tightBoundingRect(text);
}

QPainter painter(widget);
painter.setFont(font);

painter.drawText(boundingRect.topLeft(), Qt::AlignLeft | Qt::AlignTop, text);

このコードでは、"Hello, World! This is a very long text."というテキスト文字列の境界矩形を計算し、その情報に基づいてテキストのサイズを調整しています。テキストがウィジェット内に収まるように、フォントサイズが自動的に調整されます。

QFont font("Arial", 12);
QFontMetricsF fontMetrics(font);
QString text = "This is a long paragraph of text. It has multiple lines and wraps around to fit the available space. The tight bounding rect can be used to calculate the number of lines in the text.";

QRectF boundingRect = fontMetrics.tightBoundingRect(text);
int lines = boundingRect.height() / fontMetrics.height();

qDebug() << "Number of lines:" << lines;


QPainter::drawText()のboundingRect()メソッドを使用する

QPainter::drawText()関数は、テキストを描画するための関数です。この関数は、boundingRect()メソッドを提供しており、テキストの境界矩形を取得することができます。

QFont font("Arial", 12);
QPainter painter;
painter.setFont(font);

QString text = "Hello, World!";

QRectF boundingRect = painter.drawText(QRectF(0, 0, 0, 0), Qt::AlignLeft | Qt::AlignTop, text).boundingRect();

// boundingRect.x() はテキストの左端の X 座標を取得
// boundingRect.y() はテキストの上端の Y 座標を取得
// boundingRect.width() はテキストの幅を取得
// boundingRect.height() はテキストの高さ

この方法は、QFontMetricsF::tightBoundingRect()関数を直接使用するよりも、コードが簡潔になる場合があります。

QTextBlock::boundingRect()メソッドを使用する

QTextBlockクラスは、テキストブロックを表すクラスです。QTextBlock::boundingRect()メソッドは、テキストブロックの境界矩形を取得することができます。

QTextDocument document;
document.setPlainText("Hello, World!");

QTextBlock block = document.firstBlock();

QRectF boundingRect = block.boundingRect();

// boundingRect.x() はテキストブロックの左端の X 座標を取得
// boundingRect.y() はテキストブロックの上端の Y 座標を取得
// boundingRect.width() はテキストブロックの幅を取得
// boundingRect.height() はテキストブロックの高さ

この方法は、テキストブロック単位で境界矩形を計算したい場合に適しています。

QTextLayout::boundingRect()メソッドを使用する

QTextLayoutクラスは、テキストレイアウトを表すクラスです。QTextLayout::boundingRect()メソッドは、テキストレイアウトの境界矩形を取得することができます。

QTextLayout layout;
layout.setText("Hello, World!");

QRectF boundingRect = layout.boundingRect();

// boundingRect.x() はテキストレイアウトの左端の X 座標を取得
// boundingRect.y() はテキストレイアウトの上端の Y 座標を取得
// boundingRect.width() はテキストレイアウトの幅を取得
// boundingRect.height() はテキストレイアウトの高さ

この方法は、複雑なテキストレイアウトの境界矩形を計算したい場合に適しています。

QFontMetricsF::tightBoundingRect()の代替方法の選択

QFontMetricsF::tightBoundingRect()の代替方法は、状況によって異なります。以下の点を考慮して、適切な方法を選択してください。

  • コードの簡潔さ:コードが簡潔であることが重要かどうか
  • テキストレイアウト:単純なレイアウトなのか、複雑なレイアウトなのか
  • テキストの形式:単一行のテキストなのか、複数行のテキストなのか