QFont::setPointSizeF()
QFont::setPointSizeF()
は、Qtプログラミングにおいて、フォントのサイズを浮動小数点数(qreal
型)で設定するための関数です。
役割と目的
Qtでは、テキストを描画する際に使用するフォントの属性をQFont
クラスで管理します。その中でも、フォントのサイズは非常に重要な属性の一つです。setPointSizeF()
は、このフォントサイズを「ポイント」という単位で、より正確に(小数点以下も指定して)設定するために使われます。
ポイントとは?
「ポイント」は、印刷業界で伝統的に使われているフォントサイズの単位です。一般的に1ポイントは1/72インチと定義されています。setPointSizeF()
で指定するポイント数は、この物理的なサイズに基づいています。
なぜfloat
(qreal
)を使うのか?
Qtには、setPointSize()
という整数でポイントサイズを設定する関数もあります。しかし、より細かいフォントサイズ調整が必要な場合や、計算によって小数点以下の値が出てくる場合には、setPointSizeF()
が便利です。例えば、特定のスペースにテキストをぴったり収めるために、フォントサイズを動的に計算するような場合に、浮動小数点数で指定できると柔軟性が増します。
使用例
#include <QApplication>
#include <QLabel>
#include <QFont>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QLabel label;
label.setText("Hello, Qt!");
QFont font = label.font(); // 現在のフォントを取得
font.setPointSizeF(12.5); // フォントサイズを12.5ポイントに設定
label.setFont(font); // ラベルに新しいフォントを設定
label.show();
return app.exec();
}
この例では、QLabel
に表示されるテキストのフォントサイズを12.5ポイントに設定しています。
よくあるエラーと問題
-
- 原因1:
QFont
オブジェクトをウィジェットに再設定していないQFont
は値型(Value Type)です。つまり、QLabel::font()
などでフォントを取得した場合、それはそのウィジェットのフォントのコピーです。そのコピーに対してsetPointSizeF()
を呼び出しても、元のウィジェットのフォントは変更されません。変更を反映させるには、変更したQFont
オブジェクトを再度ウィジェットに設定する必要があります。// 誤った例 QLabel* label = new QLabel("Hello"); QFont font = label->font(); // フォントのコピーを取得 font.setPointSizeF(24.0); // コピーを変更したが、ウィジェットには反映されない // 正しい例 QLabel* label = new QLabel("Hello"); QFont font = label->font(); font.setPointSizeF(24.0); label->setFont(font); // 変更したフォントをウィジェットに再設定
- 原因2: スタイルシート(Qt Designerを含む)による上書き
Qt DesignerでUIを作成している場合や、アプリケーション内でスタイルシート(CSSのようなもの)を使用している場合、ウィジェットのフォント設定がスタイルシートによって上書きされることがあります。スタイルシートで
font-size
がピクセル単位(px
)で指定されていると、setPointSizeF()
で設定したポイントサイズが無視されることがあります。特に、Qt Designerで明示的にフォントサイズを設定していると、それがデフォルトとして扱われ、プログラムからの変更が適用されないことがあります。- トラブルシューティング: スタイルシートの記述を確認し、
font-size
をpt
(ポイント)単位で指定するか、スタイルシートでのフォントサイズ設定を削除してプログラムでの制御に任せることを検討してください。Qt Designerで設定したフォントサイズをリセットすることも有効です。
- トラブルシューティング: スタイルシートの記述を確認し、
- 原因3: プラットフォームごとのフォントレンダリングの違い
setPointSizeF()
で設定したポイントサイズは、すべてのプラットフォームで完全に同じピクセルサイズとしてレンダリングされるとは限りません。OSのDPI設定、フォントレンダリングエンジン(FreeType、DirectWriteなど)、利用可能なフォントの種類によって、実際の表示サイズにわずかな差が生じることがあります。- トラブルシューティング: 特定のピクセルサイズで表示したい場合は、
QFont::setPixelSize()
を使用することを検討してください。ただし、これはデバイス依存性が高くなる可能性があります。より正確なフォントの測定が必要な場合は、QFontMetrics
クラス(例:QFontMetricsF::height()
,QFontMetricsF::width()
)を使用します。
- トラブルシューティング: 特定のピクセルサイズで表示したい場合は、
- 原因4: フォントがシステムにインストールされていない、または代替フォントが選択されている
指定したフォントファミリー(例: "Arial", "Meiryo UI")がユーザーのシステムにインストールされていない場合、Qtは最も近い代替フォントを選択します。この代替フォントは、希望するポイントサイズと異なる振る舞いをすることがあります。
- トラブルシューティング:
QFontInfo
クラスを使用して、実際にQtが選択したフォントの情報を確認します。QFontInfo::family()
やQFontInfo::pointSizeF()
などを使って、期待通りのフォントが使われているか、サイズがどうなっているかを確認できます。
- トラブルシューティング:
- 原因1:
-
QFont::pixelSize()
が-1
を返す- 原因:
setPointSizeF()
やsetPointSize()
を使用してフォントサイズを設定した場合、pixelSize()
はデフォルトで-1
を返します。これは、ポイントサイズが設定された場合、ピクセルサイズが明示的に設定されていないことを示します。実際のピクセルサイズは、実行時にシステムやDPIに基づいて計算されます。 - トラブルシューティング: 実際のピクセルサイズが必要な場合は、
QFontMetricsF::height()
やQFontMetricsF::width()
など、QFontMetricsF
クラスの関数を使用してテキストの寸法を計算してください。
- 原因:
-
フォントストレッチ(
setStretch()
)と組み合わせた場合の挙動の不一致- 原因: 大文字のポイントサイズ(例えば48ポイント以上)で
QFont::setStretch()
を使用すると、期待通りの効果が得られないという報告があります。これはQtの内部的なフォントレンダリングの制限によるものかもしれません。 - トラブルシューティング: 大きなフォントサイズでテキストの幅を調整したい場合は、
QPainter::drawText()
のオーバーロードでQRectFを指定してテキストを矩形内に描画し、Qtに自動的にスケーリングさせる方法や、一時的なQImage
に描画してそれをスケーリングして表示するなどの回避策を検討してください。
- 原因: 大文字のポイントサイズ(例えば48ポイント以上)で
-
setPointSize(0)
または負の値- 原因:
setPointSizeF()
(またはsetPointSize()
) に0以下の値を設定しようとすると、Qtは警告(QFont::setPointSize: Point size <= 0
)を出すことがあります。これは無効なフォントサイズであり、通常は無視されるか、デフォルトサイズに設定されます。Qt Designerでこの問題が発生する場合、.ui
ファイルに無効な値が書き込まれている可能性があります。 - トラブルシューティング: コードまたはUIファイルで設定されているフォントサイズが正の値であることを確認してください。
- 原因:
- Qtバージョンとプラットフォームの確認: 使用しているQtのバージョンやターゲットとしているOSによって、フォントの挙動が異なる場合があります。公式ドキュメントやQtフォーラムで、特定のバージョンやプラットフォームに関する既知の問題がないか確認してください。
- DPI設定の影響: 特に高DPIディスプレイ環境では、OSのDPI設定がフォントのレンダリングに大きく影響します。Qt 5以降は高DPIサポートが改善されていますが、古いQtバージョンや特定のプラットフォームでは注意が必要です。
QApplication::setFont()
の影響を確認する: アプリケーション全体のデフォルトフォントがQApplication::setFont()
で設定されている場合、個々のウィジェットのフォントがそれに影響されることがあります。特定のウィジェットのフォントを明示的に設定すると、アプリケーションのデフォルト設定を上書きします。QFontInfo
を使用する:QFontInfo
は、QFont
オブジェクトが実際にシステム上でどのように解決されたか(どのフォントが選ばれ、どのサイズが適用されたかなど)の情報を提供します。期待通りのフォントがロードされているか、サイズがどのように解釈されているかを判断するのに非常に役立ちます。qDebug()
で確認する: フォントを設定する前後で、QFont
オブジェクトの様々なプロパティ(family()
,pointSizeF()
,pixelSize()
,italic()
,bold()
など)をqDebug()
で出力し、期待通りの値が設定されているか確認します。QFont font = label->font(); qDebug() << "Original font point size:" << font.pointSizeF(); font.setPointSizeF(18.0); qDebug() << "New font point size (set):" << font.pointSizeF(); label->setFont(font); // 実際に適用されたフォントの情報はQFontInfoから取得 QFontInfo fontInfo(label->font()); qDebug() << "Actual font point size (applied):" << fontInfo.pointSizeF(); qDebug() << "Actual font pixel size (applied):" << fontInfo.pixelSize();
基本的なフォントサイズ設定
最も一般的な使用例は、特定のウィジェットのフォントサイズを設定することです。
#include <QApplication>
#include <QLabel>
#include <QFont>
#include <QVBoxLayout> // ウィジェットを縦に並べるために使用
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget window;
QVBoxLayout *layout = new QVBoxLayout(&window);
// デフォルトフォントのラベル
QLabel *label1 = new QLabel("デフォルトフォントサイズ");
layout->addWidget(label1);
// フォントサイズを10.5ポイントに設定するラベル
QLabel *label2 = new QLabel("サイズ 10.5pt");
QFont font2 = label2->font(); // 現在のフォントのコピーを取得
font2.setPointSizeF(10.5); // 浮動小数点数でサイズを設定
label2->setFont(font2); // ウィジェットにフォントを再設定
layout->addWidget(label2);
// フォントサイズを20.0ポイントに設定し、太字にするラベル
QLabel *label3 = new QLabel("サイズ 20.0pt (太字)");
QFont font3 = label3->font();
font3.setPointSizeF(20.0);
font3.setBold(true); // 太字に設定
label3->setFont(font3);
layout->addWidget(label3);
// 指定したフォントファミリーとサイズで直接QFontオブジェクトを作成する例
QLabel *label4 = new QLabel("Times New Roman, サイズ 14.25pt");
QFont font4("Times New Roman", -1, -1, false); // まずデフォルト値で初期化
font4.setPointSizeF(14.25); // その後でポイントサイズを設定
label4->setFont(font4);
layout->addWidget(label4);
window.setWindowTitle("QFont::setPointSizeF() 例");
window.show();
return app.exec();
}
解説:
setPointSizeF()
はqreal
型(通常はdouble
のエイリアス)を受け取るため、小数点以下の値も正確に指定できます。QFont
オブジェクトは値型なので、label->font()
で取得したものを変更しても、その変更をウィジェットに反映させるためには、必ずlabel->setFont(font);
のように再設定する必要があります。
動的にフォントサイズを調整する例
例えば、ウィジェットのサイズに基づいてテキストを可能な限り大きく表示したい場合など、動的にフォントサイズを調整する際にsetPointSizeF()
が役立ちます。QFontMetricsF
クラスを使って、テキストの描画に必要なサイズを計算します。
#include <QApplication>
#include <QLabel>
#include <QFont>
#include <QFontMetricsF> // 浮動小数点数でのフォントメトリクス
#include <QVBoxLayout>
#include <QResizeEvent>
class ResizableTextLabel : public QLabel
{
public:
ResizableTextLabel(const QString &text, QWidget *parent = nullptr)
: QLabel(text, parent)
{
setMinimumSize(100, 50); // 最小サイズを設定
setAlignment(Qt::AlignCenter); // テキストを中央揃えにする
}
protected:
void resizeEvent(QResizeEvent *event) override
{
QFont font = this->font();
double currentPointSizeF = font.pointSizeF(); // 現在のポイントサイズを取得
// 現在のフォントメトリクスでテキストの幅と高さを計算
QFontMetricsF fm(font);
qreal textWidth = fm.horizontalAdvance(text());
qreal textHeight = fm.height();
// ウィジェットの幅と高さに基づいて、新しいフォントサイズを計算
// ここでは簡単な比例計算を使用
qreal targetWidthRatio = (qreal)event->size().width() / textWidth;
qreal targetHeightRatio = (qreal)event->size().height() / textHeight;
// 幅と高さのうち、小さい方の比率を採用して、テキストがはみ出さないようにする
qreal scaleFactor = qMin(targetWidthRatio, targetHeightRatio);
// 新しいポイントサイズを計算(現在のポイントサイズにスケールファクターを掛ける)
qreal newPointSizeF = currentPointSizeF * scaleFactor;
// 無効なサイズにならないように最小値を設定
if (newPointSizeF < 1.0) {
newPointSizeF = 1.0;
}
// 新しいフォントサイズを設定
font.setPointSizeF(newPointSizeF);
this->setFont(font);
QLabel::resizeEvent(event); // 親クラスのresizeEventも呼び出す
}
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
ResizableTextLabel label("リサイズ可能なテキスト");
label.resize(300, 150); // 初期サイズを設定
label.show();
return app.exec();
}
解説:
- ここではシンプルな比例計算を使用していますが、実際のアプリケーションでは、より複雑なロジック(例: 最大・最小フォントサイズ、DPIへの対応など)が必要になる場合があります。
QFontMetricsF
を使用することで、指定されたフォントでのテキストの実際のピクセル幅と高さを浮動小数点数で取得できます。これにより、より正確なサイズ調整が可能になります。resizeEvent
をオーバーライドし、ウィジェットがリサイズされるたびにフォントサイズを再計算しています。- この例では、
QLabel
を継承したカスタムウィジェットResizableTextLabel
を作成しています。
QPainter
を使用して直接グラフィックビューやカスタムウィジェットに描画する際にも、QFont::setPointSizeF()
を使用できます。
#include <QApplication>
#include <QWidget>
#include <QPainter>
#include <QFont>
#include <QFontMetricsF>
class CustomDrawingWidget : public QWidget
{
public:
CustomDrawingWidget(QWidget *parent = nullptr) : QWidget(parent)
{
setMinimumSize(400, 200);
}
protected:
void paintEvent(QPaintEvent *event) override
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing); // アンチエイリアスを有効にする
// 1. 基本的なフォント設定
QFont font1("Arial", -1, -1, false);
font1.setPointSizeF(18.5); // 18.5ポイント
painter.setFont(font1);
painter.drawText(50, 50, "こんにちは、Qt Painter! (18.5pt)");
// 2. 別のフォントとサイズ
QFont font2("Verdana", -1, QFont::Bold, true);
font2.setPointSizeF(24.75); // 24.75ポイント、太字、斜体
painter.setFont(font2);
painter.drawText(50, 100, "カスタム描画 (24.75pt, Bold, Italic)");
// 3. テキストの中心に描画するためのフォントメトリクス計算
QString textToCenter = "中央に配置されるテキスト";
QFont font3("メイリオ", -1, QFont::Normal);
font3.setPointSizeF(16.0);
painter.setFont(font3);
QFontMetricsF fm3(font3);
qreal textWidth3 = fm3.horizontalAdvance(textToCenter);
qreal textHeight3 = fm3.height();
qreal x = (width() - textWidth3) / 2.0;
qreal y = (height() - textHeight3) / 2.0 + fm3.ascent(); // ascentを足してベースラインを合わせる
painter.drawText(x, y, textToCenter);
// 描画されたテキストの境界ボックスを描画(デバッグ用)
QRectF textRect = fm3.boundingRect(textToCenter);
textRect.moveTo(x, y - fm3.ascent()); // boundingRectはベースラインから始まるため調整
painter.drawRect(textRect);
}
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
CustomDrawingWidget widget;
widget.setWindowTitle("QPainterとQFont::setPointSizeF()");
widget.show();
return app.exec();
}
解説:
QFontMetricsF
は、QPainter
が現在設定しているフォントに基づいてテキストの寸法を計算するために使用されます。これにより、テキストを正確に配置できます。特にfm3.ascent()
はベースラインを考慮する上で重要です。QPainter
のsetFont()
メソッドでQFont
オブジェクトを設定してから、drawText()
でテキストを描画します。
QFont::setPointSize()
説明
setPointSizeF()
と非常によく似ていますが、フォントサイズを整数値のポイントで設定します。小数点以下の精度が必要ない場合に、よりシンプルに利用できます。
使用例
#include <QApplication>
#include <QLabel>
#include <QFont>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QLabel label("Hello, Qt!");
QFont font = label.font();
font.setPointSize(12); // 12ポイントに設定
label.setFont(font);
label.show();
return app.exec();
}
setPointSizeF() との使い分け
setPointSize()
: 整数で十分な場合や、古いAPIとの互換性を保ちたい場合にシンプルに利用できます。setPointSizeF()
: フォントサイズをより細かく(小数点以下も含む)制御したい場合や、計算結果が浮動小数点数になる場合に適しています。
QFont::setPixelSize()
説明
フォントサイズをピクセル単位で設定します。これはポイント単位とは異なり、画面上の物理的なピクセル数に基づいてフォントのサイズを決定します。高DPIディスプレイ環境で、特定のピクセルサイズで表示したい場合に役立つことがあります。
使用例
#include <QApplication>
#include <QLabel>
#include <QFont>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QLabel label("Hello, Pixel Size!");
QFont font = label.font();
font.setPixelSize(24); // 24ピクセルに設定
label.setFont(font);
label.show();
return app.exec();
}
setPointSizeF() との使い分け
setPixelSize()
: 特定のピクセル数で厳密に表示したい場合。デバイスのDPI設定が異なる場合、同じピクセルサイズでも物理的なサイズ感が大きく変わる可能性があります(例: 96DPIと192DPIの画面では、同じ24pxでも後者の方が小さく見える)。setPointSizeF()
: 印刷などのメディアに依存しない、より「抽象的」なサイズ指定(ポイントは通常1/72インチ)。OSのDPI設定に応じて自動的にスケーリングされることが期待されます。異なるDPI設定の画面でも、見た目のサイズ感がある程度保たれる傾向があります。
スタイルシート (qss) を使用したフォントサイズ設定
説明
Qtのスタイルシート(CSSに似た構文)を使用して、ウィジェットのフォントサイズを設定できます。これは、アプリケーションのルック&フィールを一元的に管理したい場合に非常に強力です。
使用例
// main.cpp
#include <QApplication>
#include <QLabel>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QLabel label("スタイルシートでフォントサイズを設定");
// QLabel のフォントサイズを18ポイントに設定
label.setStyleSheet("QLabel { font-size: 18pt; }");
// 特定のオブジェクト名のQLabelのみに適用する場合
// label.setObjectName("myCustomLabel");
// label.setStyleSheet("QLabel#myCustomLabel { font-size: 20pt; }");
label.show();
return app.exec();
}
setPointSizeF() との使い分け
- スタイルシート: UIのテーマ設定、アプリケーション全体または特定のウィジェットのグループに一貫したスタイルを適用したい場合に適しています。デザイナーがUIの外観を調整する際にも便利です。スタイルシートでは
pt
(ポイント)やpx
(ピクセル)など、複数の単位が使用できます。 setPointSizeF()
(C++コード): プログラムのロジックに基づいて動的にフォントサイズを変更したい場合や、特定のウィジェットのフォントを個別に制御したい場合に適しています。
QApplication::setFont()
説明
アプリケーション全体のデフォルトフォントを設定します。これにより、明示的にフォントを設定しないすべてのウィジェットがこのデフォルトフォントを使用するようになります。
使用例
#include <QApplication>
#include <QLabel>
#include <QFont>
#include <QVBoxLayout>
#include <QPushButton>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
// アプリケーション全体のデフォルトフォントを設定
QFont defaultFont("Arial", -1, -1, false);
defaultFont.setPointSizeF(14.0); // 14ポイントに設定
QApplication::setFont(defaultFont);
QWidget window;
QVBoxLayout *layout = new QVBoxLayout(&window);
QLabel *label1 = new QLabel("これはアプリケーションのデフォルトフォントです");
layout->addWidget(label1);
QPushButton *button1 = new QPushButton("ボタンもデフォルトフォント");
layout->addWidget(button1);
// このQLabelだけは、明示的に異なるフォントを設定
QLabel *label2 = new QLabel("このラベルは異なるフォント");
QFont customFont = label2->font();
customFont.setPointSizeF(10.0); // 10ポイントに設定
customFont.setItalic(true);
label2->setFont(customFont);
layout->addWidget(label2);
window.setWindowTitle("QApplication::setFont() 例");
window.show();
return app.exec();
}
setPointSizeF() との使い分け
- 個別のウィジェットでの
setPointSizeF()
: アプリケーション全体のデフォルト設定を上書きし、特定のウィジェットのフォントを個別にカスタマイズしたい場合。 QApplication::setFont()
: アプリケーション全体にわたる一貫したフォントのベースラインを設定したい場合。
説明
これは直接フォントサイズを設定する方法ではありませんが、既存のフォントでテキストがどれくらいのスペースを占めるかを計算するのに非常に役立ちます。これを使って、テキストが特定の領域に収まるようにフォントサイズを動的に調整するロジックを実装できます。QFontMetricsF
は浮動小数点数での計算を提供し、より高精度です。
QFontMetrics
/QFontMetricsF
は、setPointSizeF()
を呼び出す前に「どれくらいのサイズにすべきか」を決定するための情報を提供する、補完的なツールです。