QFont::pointSizeF()

2025-06-06

以下に詳しく説明します。

フォントサイズについて

フォントのサイズを表す方法には、主に以下の2種類があります。

  1. ポイント (Point):

    • 物理的な長さを基準とした単位で、1ポイントは1/72インチと定義されています。
    • ディスプレイの解像度(DPI: Dots Per Inch)に依存しないため、異なるディスプレイでも物理的に同じサイズで表示される傾向があります(ただし、OSのDPIスケーリング設定によっては見た目の大きさが変わることもあります)。
    • Qtでは、QFont::pointSize()で整数値のポイントサイズを取得できますが、これは通常、最も近い整数値に丸められた値です。
  2. ピクセル (Pixel):

    • ディスプレイのピクセル数を基準とした単位で、1ピクセルはディスプレイ上の1ドットに相当します。
    • ディスプレイの解像度によって物理的な大きさが変わります。例えば、同じピクセルサイズのフォントでも、高DPIディスプレイでは小さく表示され、低DPIディスプレイでは大きく表示されます。
    • Qtでは、QFont::pixelSize()でピクセルサイズを取得できます。

QFont::pointSizeF() の役割

QFont::pointSizeF() は、QFont オブジェクトが設定しているフォントのポイントサイズを qreal 型(浮動小数点数)で返します。

なぜ浮動小数点数が必要なのか?

  • 特に高DPI環境では、フォントのサイズをピクセル単位で正確に制御するよりも、ポイント単位で指定し、システムのスケーリングに任せた方が、様々なデバイスで一貫した表示を実現しやすくなります。pointSizeF()は、その際に実際のレンダリングに使われる可能性のある、より精密なポイントサイズを知るために使用できます。
  • フォントのレンダリングは、内部的にはサブピクセルレベルで精密に行われることがあります。整数値のポイントサイズだけでは表現できない、より正確なサイズ情報を取得したい場合にpointSizeF()が役立ちます。

pointSize()pointSizeF() の違い

  • QFont::pointSizeF(): フォントのポイントサイズを浮動小数点数で返します。
  • QFont::pointSize(): フォントのポイントサイズを整数で返します。

多くの場合、pointSize() で十分ですが、より厳密なサイズ情報を取得したい場合や、小数点以下の値も考慮してフォントのサイズを計算したい場合に pointSizeF() が使用されます。

#include <QFont>
#include <QDebug>

int main() {
    QFont font;
    font.setPointSize(12); // ポイントサイズを12に設定

    qDebug() << "整数ポイントサイズ:" << font.pointSize();    // 12
    qDebug() << "実数ポイントサイズ:" << font.pointSizeF();   // 12.0 (またはそれに近い値)

    font.setPointSizeF(12.5); // ポイントサイズを12.5に設定

    qDebug() << "整数ポイントサイズ (12.5設定後):" << font.pointSize(); // 12 (丸められる)
    qDebug() << "実数ポイントサイズ (12.5設定後):" << font.pointSizeF(); // 12.5 (またはそれに近い値)

    return 0;
}

この例からわかるように、setPointSizeF() で設定した浮動小数点数のポイントサイズは、pointSizeF() で正確に取得できますが、pointSize() では最も近い整数に丸められて取得されます。



期待するフォントサイズと実際の表示サイズが異なる

問題の発生
setPointSizeF() で設定したサイズと、実際に画面に表示されるフォントのサイズが異なるように見えることがあります。これは特に高DPIディスプレイ環境で顕著です。

原因

  • フォントの品質とレンダリング
    特定のフォント(特にビットマップフォントなど)は、利用可能なサイズが限られている場合があります。また、アンチエイリアシングの設定やレンダリングエンジンの違いも影響します。
  • QFontInfo の使用
    QFont::pointSizeF() は「設定された」ポイントサイズを返しますが、実際にレンダリングに使用されたフォントの属性は異なる場合があります。これは、QFontInfo オブジェクトを使用して確認できます。
  • システムDPI設定
    ポイントサイズはデバイス独立な単位ですが、最終的なピクセルへの変換はオペレーティングシステムのDPI設定に依存します。DPIスケーリングが有効になっている場合、同じポイントサイズでも物理的な大きさが変わって見えます。
  • フォントマッチング
    Qtは、指定されたフォント属性(フォントファミリー、ポイントサイズ、ウェイトなど)に最も近い利用可能なフォントを探します。完全に一致するフォントがない場合、Qtは代替フォントや近似サイズを使用することがあります。

トラブルシューティング

  • 使用するフォントの確認
    システムに目的のフォントがインストールされているか確認します。QFontDatabase::hasFont() などを使用して存在を確認することもできます。
  • setPixelSize() との比較
    ポイントサイズでの指定が難しい場合、一時的に setPixelSize() を使用してピクセル単位でサイズを固定し、表示を確認することで、問題がDPIスケーリングにあるのか、フォントマッチングにあるのかを切り分けることができます。ただし、setPixelSize() はデバイス非依存性が低くなるため、通常は推奨されません。
  • DPIスケーリングの考慮
    • Qt 5以降では高DPIサポートが強化されていますが、アプリケーションがDPIスケーリングを正しく処理しているか確認します。
    • 環境変数 QT_SCALE_FACTOR や、QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); などの設定が適切か確認します。
    • Windowsの場合、アプリケーションのマニフェストファイルでDPIアウェアネス設定を確認します。
  • QFontInfo で実際のフォント情報を確認する
    QFont font;
    font.setPointSizeF(12.5); // 例
    // ... font の他の設定 (setFamily, setWeight など)
    
    QFontInfo fontInfo(font);
    qDebug() << "設定されたポイントサイズ:" << font.pointSizeF();
    qDebug() << "実際に使用されたポイントサイズ:" << fontInfo.pointSizeF();
    qDebug() << "実際に使用されたピクセルサイズ:" << fontInfo.pixelSize();
    qDebug() << "使用されたフォントファミリー:" << fontInfo.family();
    
    fontInfo.pointSizeF() の値が font.pointSizeF() の値と異なる場合、Qtが代替のフォントまたはサイズを選択した可能性があります。

pointSizeF() が -1 を返す

問題の発生
QFont::pointSizeF()-1.0 を返すことがあります。

原因

  • setPixelSize() が使用された場合
    setPixelSize() を使用してフォントのサイズをピクセル単位で設定した場合、pointSizeF()-1.0 を返すことがあります。これは、ポイントサイズが明示的に設定されていないためです。
  • デフォルトコンストラクタで作成された QFont
    QFont オブジェクトをデフォルトコンストラクタ QFont() で作成し、setPointSize()setPointSizeF() を明示的に呼び出していない場合、フォントのサイズはシステム依存のデフォルト値になります。この時、pointSizeF()-1.0 を返すことがあります。これは、明示的にポイントサイズが設定されていないことを示します。

トラブルシューティング

  • pixelSize() との使い分け
    ポイントサイズとピクセルサイズは排他的な関係にある場合があります。pointSizeF()-1.0 を返す場合、pixelSize() を確認してみてください。どちらか一方が有効な値を持つはずです。
    QFont font;
    // font.setPixelSize(20); // こちらを使用した場合
    qDebug() << "ポイントサイズF:" << font.pointSizeF(); // -1.0 の可能性
    qDebug() << "ピクセルサイズ:" << font.pixelSize(); // 20 の可能性
    
    font.setPointSizeF(10.0); // こちらを使用した場合
    qDebug() << "ポイントサイズF:" << font.pointSizeF(); // 10.0 の可能性
    qDebug() << "ピクセルサイズ:" << font.pixelSize(); // 変換されたピクセル値
    
  • 常にサイズを設定する
    QFont オブジェクトを作成したら、setPointSize() または setPointSizeF() で明示的にサイズを設定することをお勧めします。

フォントの変更がUIに反映されない

問題の発生
QFont オブジェクトの pointSizeF() を変更しても、関連するUI要素(QLabelQPushButtonなど)のフォントサイズが変わらない。

原因

  • スケーラブルではないフォント
    使用しているフォントがスケーラブル(TrueType, OpenTypeなど)でない場合、指定した任意のサイズにレンダリングできないことがあります。
  • スタイルシートとの競合
    Qtスタイルシートを使用してウィジェットのフォントが設定されている場合、C++コードでの setFont() の呼び出しがスタイルシートの設定によって上書きされることがあります。スタイルシートは通常、ウィジェットのプロパティよりも優先されます。
  • setFont() の呼び忘れ
    QFont オブジェクトを変更しただけでは、UI要素のフォントは自動的に更新されません。変更された QFont オブジェクトを再度ウィジェットの setFont() メソッドに渡す必要があります。

トラブルシューティング

  • スケーラブルなフォントの使用
    システムにインストールされている一般的なTrueTypeやOpenTypeフォント(例: Arial, Helvetica, Noto Sans CJK JPなど)を使用するようにします。
  • スタイルシートの確認
    • アプリケーションやウィジェットのスタイルシート(.qss ファイルまたは setStyleSheet())に font-size プロパティが設定されていないか確認します。
    • スタイルシートで font-size が設定されている場合は、そちらを調整するか、スタイルシートを削除してC++コードで制御するようにします。
  • setFont() を再呼び出しする
    QLabel *label = new QLabel("Hello");
    QFont font = label->font(); // 現在のフォントを取得
    font.setPointSizeF(20.0);   // サイズを変更
    label->setFont(font);       // 変更を適用
    

浮動小数点精度に関する問題

問題の発生
setPointSizeF(X) で設定したにも関わらず、pointSizeF() が完全に X とは異なる、わずかに異なる値を返すことがあります。

原因

  • 内部表現
    Qtは、内部的にポイントサイズを「デシポイント (deci-points)」など、特定の精度で管理している場合があります。これにより、設定した qreal 値が内部表現に最も近い値に丸められ、再度取得する際に元の値とわずかに異なることがあります。
  • 浮動小数点数の限界
    qreal は浮動小数点数であり、すべての実数を正確に表現できるわけではありません。内部的な変換や丸め処理によって、わずかな誤差が生じることがあります。

トラブルシューティング

  • QFontInfo での確認
    上記のように、QFontInfo を使って実際に使用されているフォントの属性を確認することで、レンダリングエンジンの都合によるものか、それとも単なる数値の丸め誤差なのかを判断できます。
  • 許容範囲内の誤差とみなす
    ほとんどの場合、このわずかな誤差は視覚的な違いを生むことはなく、許容範囲内です。厳密な比較が必要な場合は、直接的な等値比較ではなく、許容範囲内の比較(例: qAbs(value1 - value2) < epsilon)を使用することを検討します。

問題の発生
同じ pointSizeF() を設定しても、Windows、macOS、Linuxなどの異なるOSでフォントの見た目が異なる。

原因

  • フォントヒンティング/アンチエイリアシング
    OSやグラフィックドライバの設定により、フォントのヒンティング(グリッドへのスナップ)やアンチエイリアシングの適用方法が異なり、これが文字の太さや鮮明さに影響を与えます。
  • DPI/スケーリングの違い
    各OSのDPI計算やスケーリング方法が異なるため、同じポイントサイズでも物理的な大きさが変わって見えます。
  • フォントマッチングの違い
    各OSには独自のフォントレンダリングエンジンとフォントマッチングアルゴリズムがあります。指定されたフォントファミリーが特定のOSに存在しない場合、OSは異なる代替フォントを選択する可能性があり、その結果、見た目が変わります。
  • 最終確認は各プラットフォームで
    開発段階で各ターゲットプラットフォームでの表示を確認し、必要に応じてフォントサイズやレイアウトを微調整することが重要です。
  • QtのDPIスケーリング機能の活用
    Qt 5.6以降で導入された高DPIサポート(Qt::AA_EnableHighDpiScalingQT_FONT_DPI 環境変数など)を適切に活用し、アプリケーションがDPIの変化に適応できるようにします。
  • QFont::StyleStrategy の設定
    QFont::setStyleStrategy() を使用して、フォントのマッチング戦略(例: QFont::PreferAntialiasQFont::NoFontMerging など)を調整することで、レンダリングの動作をある程度制御できます。
  • 共通フォントの使用
    複数のプラットフォームで広く利用可能なフォント(例: Arial, Times New Roman, Noto Sansなど)を使用することで、フォントマッチングによる違いを減らすことができます。


基本的な使用例:フォントサイズの設定と取得

この例では、QFont オブジェクトを作成し、setPointSizeF() で浮動小数点数のポイントサイズを設定し、その後 pointSizeF() でその値を取得します。

#include <QApplication>
#include <QLabel>
#include <QFont>
#include <QDebug> // デバッグ出力用

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

    // QFontオブジェクトの作成
    QFont myFont;

    // 1. setPointSizeF() でフォントサイズを浮動小数点数で設定
    myFont.setPointSizeF(14.75); // 例えば、14.75ポイントに設定

    // 2. pointSizeF() で設定されたフォントサイズを取得
    qreal actualPointSize = myFont.pointSizeF();
    qDebug() << "設定されたポイントサイズ (pointSizeF()):" << actualPointSize;

    // 参考: 整数値のポイントサイズも取得してみる
    int integerPointSize = myFont.pointSize();
    qDebug() << "設定されたポイントサイズ (pointSize()):" << integerPointSize;

    // QLabelにフォントを適用して表示
    QLabel label("Hello, Qt with precise font size!");
    label.setFont(myFont);
    label.show();

    // もう少し大きなサイズを設定してみる
    myFont.setPointSizeF(20.33);
    label.setFont(myFont); // フォントを再適用
    qDebug() << "変更後のポイントサイズ (pointSizeF()):" << myFont.pointSizeF();

    return app.exec();
}

解説

  • myFont.pointSize(); は整数値を返すため、14.75 の場合は 15 と出力されることが多いです(丸められます)。
  • qreal actualPointSize = myFont.pointSizeF();:設定された浮動小数点数のポイントサイズを取得します。qDebug() で確認すると、14.75 (または非常に近い値) が出力されるはずです。
  • myFont.setPointSizeF(14.75);:フォントのポイントサイズを14.75に設定します。

QFontInfo との連携:実際に使用されるフォントサイズの確認

QFont::pointSizeF() は「設定された」フォントサイズを返しますが、実際にシステムが選択し、描画に使用するフォントのサイズは異なる場合があります。これを QFontInfo を使って確認します。

#include <QApplication>
#include <QLabel>
#include <QFont>
#include <QFontInfo>
#include <QDebug>

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

    QLabel label("このテキストのフォント情報を確認します。");

    QFont requestedFont;
    requestedFont.setFamily("Arial"); // 存在しない可能性のあるフォントを設定してみる
    requestedFont.setPointSizeF(18.2); // 浮動小数点数でサイズを設定
    requestedFont.setBold(true);

    label.setFont(requestedFont); // QLabelにフォントを適用

    // QFontInfo を使って実際に使用されているフォント情報を取得
    QFontInfo actualFontInfo(label.font()); // QLabelに適用されたフォントからQFontInfoを作成

    qDebug() << "--- 要求されたフォント情報 ---";
    qDebug() << "ファミリ:" << requestedFont.family();
    qDebug() << "ポイントサイズF:" << requestedFont.pointSizeF();
    qDebug() << "太字:" << requestedFont.bold();

    qDebug() << "\n--- 実際に使用されているフォント情報 (QFontInfo) ---";
    qDebug() << "ファミリ:" << actualFontInfo.family();
    qDebug() << "ポイントサイズF:" << actualFontInfo.pointSizeF();
    qDebug() << "ピクセルサイズ:" << actualFontInfo.pixelSize(); // ピクセルサイズも重要
    qDebug() << "太字:" << actualFontInfo.bold();
    qDebug() << "代替フォントか:" << actualFontInfo.substitute(); // 代替フォントが使われたか

    label.show();
    return app.exec();
}

解説

  • actualFontInfo.substitute():要求したフォントファミリーが見つからず、代替フォントが使用された場合に true を返します。
  • actualFontInfo.pixelSize():実際に描画に使用されているフォントのピクセルサイズを取得します。高DPI環境では、pointSizeF()pixelSize() の関係が重要になります。
  • actualFontInfo.pointSizeF():実際に描画に使用されているフォントのポイントサイズを取得します。
  • QFontInfo actualFontInfo(label.font());QLabel に現在適用されているフォントから QFontInfo オブジェクトを作成します。これにより、Qtのフォントマッチングプロセスを経て実際に使用されているフォントの詳細な情報を得られます。

動的なフォントサイズ調整の例

アプリケーションのサイズやコンテキストに基づいて、フォントサイズを動的に調整するシナリオです。

#include <QApplication>
#include <QWidget>
#include <QLabel>
#include <QVBoxLayout>
#include <QSlider>
#include <QFont>
#include <QDebug>

class FontSizeAdjuster : public QWidget {
    Q_OBJECT // シグナル/スロットを使用する場合に必要

public:
    FontSizeAdjuster(QWidget *parent = nullptr) : QWidget(parent) {
        setWindowTitle("フォントサイズ調整");

        label = new QLabel("テキストサイズをスライダーで調整してください。");
        label->setAlignment(Qt::AlignCenter);

        slider = new QSlider(Qt::Horizontal);
        slider->setRange(80, 400); // 8.0ポイントから40.0ポイントまで (10倍して整数で扱う)
        slider->setValue(160); // 初期値16.0ポイント

        // レイアウト
        QVBoxLayout *layout = new QVBoxLayout(this);
        layout->addWidget(label);
        layout->addWidget(slider);

        // スライダーの値が変更されたときにフォントサイズを更新する
        connect(slider, &QSlider::valueChanged, this, &FontSizeAdjuster::updateFontSize);

        // 初期フォントサイズを設定
        updateFontSize(slider->value());
    }

private slots:
    void updateFontSize(int sliderValue) {
        // スライダーの値を10で割ってポイントサイズにする
        qreal newPointSize = static_cast<qreal>(sliderValue) / 10.0;

        QFont currentFont = label->font(); // 現在のフォントを取得
        currentFont.setPointSizeF(newPointSize); // 新しいポイントサイズを設定
        label->setFont(currentFont); // QLabelにフォントを再適用

        qDebug() << "設定されたポイントサイズ:" << newPointSize;
        qDebug() << "ラベルの現在のポイントサイズF:" << label->font().pointSizeF(); // QLabelのフォントから取得
    }

private:
    QLabel *label;
    QSlider *slider;
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    FontSizeAdjuster adjuster;
    adjuster.show();
    return app.exec();
}

#include "main.moc" // MOC (Meta-Object Compiler) が生成するファイル

解説

  • label->font().pointSizeF() を呼び出すことで、QLabelに実際に適用されているフォントのポイントサイズを確認できます。
  • 変更された QFont オブジェクトを label->setFont(currentFont); で再度ラベルに設定することで、変更がUIに反映されます。
  • label->font() で現在のフォントを取得し、その QFont オブジェクトに対して setPointSizeF() を呼び出してサイズを変更します。
  • updateFontSize スロットで、スライダーの整数値 (sliderValue) を 10.0 で割って浮動小数点数のポイントサイズ (qreal newPointSize) を計算します。
  • QSlider を使用して、ユーザーがフォントサイズを動的に変更できるようにします。

QPainter でテキストを描画する際のフォント設定

QPainter を使用してウィジェットや画像に直接テキストを描画する際にも QFont::pointSizeF() を利用できます。

#include <QApplication>
#include <QWidget>
#include <QPainter>
#include <QFont>
#include <QDebug>

class CustomPaintWidget : public QWidget {
public:
    CustomPaintWidget(QWidget *parent = nullptr) : QWidget(parent) {
        setWindowTitle("カスタムペイントとフォント");
        setFixedSize(400, 200);
    }

protected:
    void paintEvent(QPaintEvent *event) override {
        Q_UNUSED(event);

        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing); // アンチエイリアシングを有効にする

        QFont customFont;
        customFont.setFamily("Times New Roman"); // フォントファミリー
        customFont.setPointSizeF(24.5); // 浮動小数点数でサイズを指定
        customFont.setItalic(true); // イタリック体

        painter.setFont(customFont); // QPainterにフォントを設定

        // 描画するテキスト
        QString text = "Precise Font Size with QPainter!";

        // テキストの描画位置
        QRect rect(20, 50, 360, 100);

        // テキストの描画
        painter.drawText(rect, Qt::AlignLeft | Qt::AlignTop, text);

        // 描画に使われたフォント情報を確認
        QFontInfo usedFontInfo(painter.font());
        qDebug() << "--- QPainterで描画されたフォント情報 ---";
        qDebug() << "ファミリ:" << usedFontInfo.family();
        qDebug() << "ポイントサイズF:" << usedFontInfo.pointSizeF();
        qDebug() << "ピクセルサイズ:" << usedFontInfo.pixelSize();
        qDebug() << "イタリック:" << usedFontInfo.italic();
    }
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    CustomPaintWidget widget;
    widget.show();
    return app.exec();
}

解説

  • QFontInfo usedFontInfo(painter.font());QPainter に現在設定されているフォントの情報を取得し、実際に描画に使用されたフォントの詳細を確認できます。
  • painter.drawText(...):設定されたフォントを使用してテキストを描画します。
  • painter.setFont(customFont);:作成したフォントを QPainter に設定します。これ以降の描画操作はこのフォントで行われます。
  • customFont.setPointSizeF(24.5);QPainter に適用するフォントのサイズを24.5ポイントに設定します。
  • QPainter painter(this);:現在のウィジェットに描画するための QPainter オブジェクトを作成します。

これらの例は、QFont::pointSizeF() がQtアプリケーションでどのように利用され、フォントのより正確なサイズ制御に役立つかを示しています。 Qt プログラミングにおける QFont::pointSizeF() の使い方を理解するために、いくつかの具体的なコード例を挙げます。これらの例は、QFont オブジェクトの作成、サイズの取得と設定、そしてUIウィジェットへの適用方法を示しています。

例1: 基本的な pointSizeF() の使用

#include <QApplication>
#include <QLabel>
#include <QFont>
#include <QDebug> // デバッグ出力用

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

    // QFont オブジェクトを作成
    QFont myFont;

    // 浮動小数点数のポイントサイズを設定
    qreal desiredPointSize = 10.5;
    myFont.setPointSizeF(desiredPointSize);
    qDebug() << "設定されたポイントサイズ (setPointSizeF):" << myFont.pointSizeF();

    // 別のポイントサイズを設定し、確認
    myFont.setPointSizeF(15.25);
    qDebug() << "再設定後のポイントサイズ (setPointSizeF):" << myFont.pointSizeF();

    // 整数ポイントサイズも確認
    qDebug() << "再設定後の整数ポイントサイズ (pointSize):" << myFont.pointSize();

    // QLabel を作成し、フォントを適用
    QLabel *label = new QLabel("Hello, Qt with precise font size!");
    label->setFont(myFont);
    label->show();

    // 実際のラベルのフォント情報も確認
    QFontInfo labelFontInfo(label->font());
    qDebug() << "ラベルの実際のポイントサイズ (QFontInfo::pointSizeF):" << labelFontInfo.pointSizeF();
    qDebug() << "ラベルの実際のピクセルサイズ (QFontInfo::pixelSize):" << labelFontInfo.pixelSize();

    return app.exec();
}

解説

  • QFontInfo labelFontInfo(label->font());: QFontInfo は、実際にシステムが選択したフォントの情報を取得するために使用します。QFont::pointSizeF() は「要求された」サイズを返しますが、QFontInfo::pointSizeF() は「実際に使用された」サイズを返します。両者が異なる場合があることを理解することが重要です。
  • QLabel *label = new QLabel(...); label->setFont(myFont);: 作成したフォントを QLabel ウィジェットに適用します。
  • myFont.pointSize();: 整数に丸められたポイントサイズを取得します。setPointSizeF(15.25) の後では 15 が返されるはずです。
  • myFont.pointSizeF();: 設定された浮動小数点数のポイントサイズを取得します。
  • myFont.setPointSizeF(desiredPointSize);: ここでフォントのポイントサイズを浮動小数点数で設定します。

例2: DPIスケーリングを考慮したフォントサイズ調整

高DPIディスプレイ環境では、OSのDPI設定に応じてフォントサイズが自動的にスケーリングされることがあります。pointSizeF() はこのスケーリングの影響を受ける可能性があります。この例では、QScreen を使用してDPI情報を取得し、それを基にフォントサイズを調整する可能性を示唆します。

注意
Qtは通常、高DPIディスプレイで自動的にフォントをスケーリングするため、開発者が手動でDPIを計算してフォントサイズを調整する必要はほとんどありません。この例は、DPI情報の取得方法と、もし手動で調整が必要な場合の考え方を示すものです。

#include <QApplication>
#include <QLabel>
#include <QFont>
#include <QDebug>
#include <QScreen> // DPI情報を取得するために必要

int main(int argc, char *argv[]) {
    // Qt 5.6以降で高DPIスケーリングを有効にする推奨設定
    // main関数の一番最初に記述する
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); // DPIスケーリングを有効にする
    QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);    // 高DPIピックスマップを使用する

    QApplication app(argc, argv);

    // メインスクリーンを取得
    QScreen *screen = app.primaryScreen();
    qreal dpiX = screen->logicalDotsPerInchX();
    qreal dpiY = screen->logicalDotsPerInchY();
    qDebug() << "スクリーンDPI (X/Y):" << dpiX << "/" << dpiY;

    // 基本となるポイントサイズ
    qreal basePointSize = 12.0;

    // QFont オブジェクトを作成
    QFont font;
    font.setFamily("Arial"); // 任意のフォントファミリー

    // basePointSize を設定
    font.setPointSizeF(basePointSize);
    qDebug() << "設定されたポイントサイズ:" << font.pointSizeF();

    // ラベルを作成し、フォントを適用
    QLabel *label1 = new QLabel("デフォルトのフォントサイズ");
    label1->setFont(font);
    label1->setGeometry(50, 50, 300, 30); // 位置とサイズを設定

    // DPIに基づいてフォントサイズを調整する(例: 100% DPIを基準とする場合)
    // 通常、Qtが自動的に処理するため、これは冗長な場合が多い
    qreal standardDpi = 96.0; // 一般的なWindowsの標準DPI
    qreal adjustedPointSize = basePointSize * (dpiX / standardDpi);
    QFont adjustedFont;
    adjustedFont.setFamily("Arial");
    adjustedFont.setPointSizeF(adjustedPointSize);

    QLabel *label2 = new QLabel("DPI調整後のフォントサイズ (手動調整)");
    label2->setFont(adjustedFont);
    label2->setGeometry(50, 100, 400, 30);

    // QFontInfo で実際のレンダリングサイズを確認
    QFontInfo fontInfo1(label1->font());
    qDebug() << "Label1 の実際のポイントサイズ:" << fontInfo1.pointSizeF();
    qDebug() << "Label1 の実際のピクセルサイズ:" << fontInfo1.pixelSize();

    QFontInfo fontInfo2(label2->font());
    qDebug() << "Label2 の実際のポイントサイズ:" << fontInfo2.pointSizeF();
    qDebug() << "Label2 の実際のピクセルサイズ:" << fontInfo2.pixelSize();

    label1->show();
    label2->show();

    return app.exec();
}

解説

  • この例の「手動調整」部分は、Qt::AA_EnableHighDpiScaling が有効な場合は基本的に不要です。Qtが自動的に適切なポイントサイズへの変換とレンダリングを行うためです。しかし、DPIの概念と pointSizeF() の関連を理解するのに役立ちます。
  • QScreen::logicalDotsPerInchX(): スクリーンごとの論理DPIを取得します。
  • QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);: これを呼び出すことで、QtアプリケーションはOSのDPI設定に合わせて自動的にUI要素(フォントを含む)をスケーリングします。通常、これで十分であり、手動でのフォントサイズ調整は不要です。

QPainter を使用してカスタム描画を行う場合も、QFont::pointSizeF() を利用できます。

#include <QApplication>
#include <QWidget>
#include <QPainter>
#include <QFont>
#include <QFontInfo>
#include <QDebug>

class CustomPaintWidget : public QWidget {
public:
    CustomPaintWidget(QWidget *parent = nullptr) : QWidget(parent) {
        setWindowTitle("QFont::pointSizeF() with QPainter");
        resize(400, 200);
    }

protected:
    void paintEvent(QPaintEvent *event) override {
        Q_UNUSED(event);
        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing); // アンチエイリアシングを有効にする

        QFont font;
        font.setFamily("Segoe UI"); // Windowsの標準フォント
        font.setWeight(QFont::Bold);

        qreal size1 = 18.7;
        font.setPointSizeF(size1);
        painter.setFont(font);
        painter.drawText(50, 50, QString("Point size: %1 (set: %2)").arg(painter.font().pointSizeF()).arg(size1));

        qreal size2 = 25.3;
        font.setPointSizeF(size2);
        painter.setFont(font);
        painter.drawText(50, 100, QString("Point size: %1 (set: %2)").arg(painter.font().pointSizeF()).arg(size2));

        // QFontInfo で実際に使用されたフォントの情報を確認
        QFontInfo painterFontInfo(painter.font());
        qDebug() << "Painterの現在のフォント情報:";
        qDebug() << "  ファミリー:" << painterFontInfo.family();
        qDebug() << "  ポイントサイズF (painter.font()):" << painter.font().pointSizeF();
        qDebug() << "  ポイントサイズF (QFontInfo):" << painterFontInfo.pointSizeF();
        qDebug() << "  ピクセルサイズ (QFontInfo):" << painterFontInfo.pixelSize();
        qDebug() << "  Exact Match:" << painterFontInfo.exactMatch(); // 指定したフォントと完全に一致したか
    }
};

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

    CustomPaintWidget widget;
    widget.show();

    return app.exec();
}
  • painter.font().pointSizeF(): QPainter が現在使用しているフォントの pointSizeF() を取得します。
  • painter.drawText(...): 指定したフォントでテキストを描画します。
  • painter.setFont(font);: QPainter に使用するフォントを設定します。
  • QPainter painter(this);: ウィジェット上で描画するための QPainter オブジェクトを作成します。


説明

QFont::setPointSize(int pointSize) は、フォントのポイントサイズを整数値で設定および取得する最も一般的な方法です。多くのアプリケーションでは、この粒度で十分です。

利点

  • 視覚的差異の少なさ
    多くのケースで、小数点以下のわずかな違いは人間の目にはほとんど区別できません。
  • 互換性
    多くの既存のQtアプリケーションやAPIで広く使用されています。
  • シンプルさ
    整数値なので、扱いが非常に簡単です。

欠点

  • pointSizeF() との不一致
    setPointSize(10) と設定しても、pointSizeF()10.0 以外の値(例えば 9.999...10.000...1)を返す可能性は低いですが、理論的には起こり得ます(ただし稀です)。
  • 精度
    ポイントサイズを整数に丸めるため、10.5pt のような正確なサイズを指定することはできません。設定しても、内部で丸められます。
#include <QApplication>
#include <QLabel>
#include <QFont>
#include <QDebug>

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

    QFont font;
    font.setFamily("Arial");

    // 整数ポイントサイズを設定
    int desiredPointSize = 12;
    font.setPointSize(desiredPointSize);

    qDebug() << "設定されたポイントサイズ (int):" << font.pointSize();
    qDebug() << "設定されたポイントサイズ (float):" << font.pointSizeF(); // 12.0が返るはず

    QLabel *label = new QLabel("Hello, setPointSize!");
    label->setFont(font);
    label->show();

    return app.exec();
}

QFont::setPixelSize() を使用する

QFont::setPixelSize(int pixelSize) は、フォントのサイズをピクセル単位で設定します。この方法は、特定のピクセルグリッドにフォントを合わせたい場合や、ディスプレイのDPIに関わらず厳密なピクセルサイズで表示したい場合に有用です。

  • 固定サイズ
    特定のグラフィックデザインやUIレイアウトで、フォントが常に同じピクセルサイズで表示されることを保証したい場合に役立ちます。
  • ピクセル単位での正確な制御
    ディスプレイの物理的なピクセル数に基づいてフォントサイズを直接指定できます。
  • pointSize()/pointSizeF() との非互換
    setPixelSize() を使用すると、pointSize()pointSizeF()-1 を返すか、あるいは無効な値を返すことがあります。これは、フォントサイズがポイント単位で明示的に設定されていないためです。
  • デバイス非依存性の欠如
    同じピクセルサイズのフォントでも、異なるDPIのディスプレイ(例: 通常のモニターとRetinaディスプレイ)では物理的な大きさが異なります。これにより、ユーザー体験の一貫性が失われる可能性があります。
#include <QApplication>
#include <QLabel>
#include <QFont>
#include <QDebug>

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

    QFont font;
    font.setFamily("Verdana");

    // ピクセルサイズを設定
    int desiredPixelSize = 24; // 24ピクセル
    font.setPixelSize(desiredPixelSize);

    qDebug() << "設定されたピクセルサイズ:" << font.pixelSize();
    qDebug() << "ポイントサイズF (setPixelSize後に取得):" << font.pointSizeF(); // -1.0 が返る可能性が高い

    QLabel *label = new QLabel("Hello, setPixelSize!");
    label->setFont(font);
    label->show();

    return app.exec();
}

Qtスタイルシート (setStyleSheet()) を使用する

Qtスタイルシートは、CSSのような構文でUIの見た目をカスタマイズする方法です。フォントのサイズもスタイルシートで指定できます。

  • 優先順位
    通常、C++コードでの setFont() よりもスタイルシートの設定が優先されます。
  • 動的な変更
    実行時にスタイルシートを切り替えることで、アプリケーションの見た目を簡単に変更できます。
  • テーマ設定
    アプリケーション全体のテーマを統一的に適用するのに適しています。
  • 宣言的
    コードから見た目の設定を分離できるため、UIデザインの管理が容易になります。
  • デバッグの複雑さ
    スタイルシートが複数の場所で定義されている場合(例: アプリケーション全体、特定のウィジェット)、どの設定が適用されているかを追跡するのが難しい場合があります。
  • プログラマブルな制御の限界
    実行時にフォントサイズを動的に計算して設定するような複雑なロジックには不向きです。
#include <QApplication>
#include <QLabel>

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

    QLabel *label1 = new QLabel("Label 1: Default Font Size");
    QLabel *label2 = new QLabel("Label 2: Large Font Size via Style Sheet");

    // スタイルシートでフォントサイズを設定
    // "pt" (ポイント) または "px" (ピクセル) 単位で指定可能
    label2->setStyleSheet("font-size: 20pt; color: blue;"); // ポイント単位
    // label2->setStyleSheet("font-size: 30px; color: blue;"); // ピクセル単位

    // ウィジェットの配置
    label1->setGeometry(50, 50, 300, 30);
    label2->setGeometry(50, 100, 300, 30);

    label1->show();
    label2->show();

    return app.exec();
}

QFontDatabase を使用する

QFontDatabase クラスは、システムで利用可能なフォントに関する情報を提供するだけでなく、特定のフォント属性に最も近いフォントを検索したり、カスタムフォントをアプリケーションにロードしたりするのに役立ちます。直接フォントサイズを設定するものではありませんが、フォント選択の文脈で関連します。

  • カスタムフォントのロード
    アプリケーションにバンドルされたフォントや、システムにインストールされていないフォントを使用できます。
  • フォントの列挙
    利用可能なすべてのフォントファミリーを列挙できます。
  • フォントの可用性の確認
    特定のフォントがシステムに存在するかどうかを確認できます。
  • フォントサイズを直接制御するものではありません。
#include <QApplication>
#include <QLabel>
#include <QFont>
#include <QFontDatabase>
#include <QDebug>

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

    // 利用可能なフォントファミリーを列挙
    qDebug() << "利用可能なフォントファミリー:";
    foreach (const QString &family, QFontDatabase::families()) {
        qDebug() << family;
    }

    // 特定のフォントファミリーが存在するか確認
    QString preferredFont = "Meiryo UI"; // Windowsのフォント例
    if (QFontDatabase::has      Font(preferredFont)) {
        qDebug() << preferredFont << "は存在します。";
        QFont font(preferredFont);
        font.setPointSizeF(14.5); // pointSizeF() と組み合わせて使用
        QLabel *label = new QLabel("Hello, " + preferredFont + "!");
        label->setFont(font);
        label->show();
    } else {
        qDebug() << preferredFont << "は存在しません。代替フォントを使用します。";
        QLabel *label = new QLabel("Hello, Default Font!");
        // デフォルトフォントが使われる
        label->show();
    }

    return app.exec();
}

どの方法を選ぶべきか?

  • 特定のフォントの確認やロード
    QFontDatabase を他のフォント設定方法と組み合わせて使用します。
  • UIデザインの分離と柔軟な見た目の変更
    Qtスタイルシートを使用します。アプリケーションのテーマ設定に非常に強力です。
  • ピクセル単位での厳密な制御が必要な場合
    QFont::setPixelSize() を使用します。ただし、異なるDPIのディスプレイでの見た目の差異に注意が必要です。
  • より精密な制御が必要な場合
    QFont::pointSizeF() を使用します。特に、フォントの微細なサイズ調整や、DPIスケーリング環境でのより正確な表示が必要な場合に適しています。
  • 最も一般的な用途
    QFont::setPointSize() を使用します。シンプルで多くのシナリオに適しています。