Qt GUIで高DPIディスプレイの壁を乗り越える:QGuiApplication::highDpiScaleFactorRoundingPolicy()の使い方


QGuiApplication::highDpiScaleFactorRoundingPolicy() は、この拡大率をどのように決定するかを制御します。具体的には、以下の3つのポリシーから選択できます。

  • Round: スケーリング率を最も近い整数に丸めます。
  • Ceiling: スケーリング率を常に上方向に丸めます。つまり、小数点以下の部分は切り上げられます。
  • Floor: スケーリング率を常に下方向に丸めます。つまり、小数点以下の部分は切り捨てられます。

デフォルトのポリシーは Round です。

以下は、QGuiApplication::highDpiScaleFactorRoundingPolicy() の使い方の例です。

QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::Floor);

このコードは、すべてのウィジェットのスケーリング率を常に下方向に丸めるように設定します。

QGuiApplication::highDpiScaleFactorRoundingPolicy() は、アプリケーション全体のスケーリングポリシーを設定する関数です。個々のウィジェットのスケーリングポリシーを設定したい場合は、QWidget::setHighDpiScaleFactorRoundingPolicy() 関数を使用します。

  • QGuiApplication::highDpiScaleFactorRoundingPolicy() は、Qt 5.6以降で使用できます。
  • 高DPIディスプレイは、近年ますます普及しています。そのため、Qt GUIアプリケーションを開発する際には、高DPIディスプレイでの表示を考慮することが重要です。


#include <QApplication>
#include <QLabel>

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

  // アプリケーション全体のスケーリングポリシーを "Floor" に設定
  QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::Floor);

  // ラベルを作成
  QLabel label("Hello, Qt!");
  label.show();

  return app.exec();
}

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

  • ラベルのテキストのサイズは、ピクセル単位ではなく、論理単位で指定されます。つまり、フォントサイズをポイントで指定すると、高DPIディスプレイでも読みやすいサイズで表示されます。
  • 高DPIディスプレイでは、ラベルのテキストが従来のディスプレイよりも大きく表示されます。
#include <QApplication>
#include <QLabel>

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

  // ラベルを作成
  QLabel label("Hello, Qt!");

  // ラベルのスケーリングポリシーを "Ceiling" に設定
  label.setHighDpiScaleFactorRoundingPolicy(Qt::Ceiling);

  label.show();

  return app.exec();
}
  • ラベルのテキストのサイズは、ピクセル単位ではなく、論理単位で指定されます。つまり、フォントサイズをポイントで指定すると、高DPIディスプレイでも読みやすいサイズで表示されます。
  • 高DPIディスプレイでは、ラベルのテキストが従来のディスプレイよりも少し大きく表示されます。


  • スケーリング率を任意の値に設定できない。
  • 個々のウィジェットのスケーリングポリシーを個別に設定できない。
  • アプリケーション全体のスケーリングポリシーしか設定できない。

これらの制限を克服するために、QGuiApplication::highDpiScaleFactorRoundingPolicy() の代替方法として、以下の方法が考えられます。

個々のウィジェットの setHighDpiScaleFactor() 関数を使用する

QWidget::setHighDpiScaleFactor() 関数は、個々のウィジェットのスケーリング率を設定することができます。この関数は、小数点以下の値を指定することができるので、より柔軟なスケーリングが可能になります。

QLabel label("Hello, Qt!");
label.setHighDpiScaleFactor(1.2);
label.show();

このコードは、ラベルのスケーリング率を 1.2 倍に設定します。

スタイルシートを使用する

スタイルシートを使用して、個々のウィジェットのスケーリングを制御することもできます。

QLabel {
  transform-scale: 1.2;
}

このスタイルシートは、すべてのラベルのスケーリング率を 1.2 倍に設定します。

カスタムスケーリングロジックを実装する

上記の方法で実現できない場合は、カスタムスケーリングロジックを実装することもできます。この方法は、より高度なスケーリング制御が必要な場合に有効です。

Qt 6 以降の QWindow::devicePixelRatio() 関数を使用する

Qt 6 以降では、QWindow::devicePixelRatio() 関数を使用して、デバイスのピクセル密度を取得することができます。この値を使用して、ウィジェットのスケーリング率を計算することができます。

QLabel label("Hello, Qt!");
label.setContentsMargins(10);
float scaleFactor = label.window()->devicePixelRatio();
label.setFont(label.font().scaled(scaleFactor));
label.show();

このコードは、ラベルのフォントサイズをデバイスのピクセル密度に合わせて調整します。

代替方法利点欠点
QWidget::setHighDpiScaleFactor()個々のウィジェットを個別に制御できるアプリケーション全体のスケーリングポリシーを設定できない
スタイルシートコードが簡潔になる複雑なスケーリングロジックを実装できない
カスタムスケーリングロジック柔軟性が高い開発コストが高い
QWindow::devicePixelRatio() (Qt 6 以降)最新の Qt フレームワークに対応しているQt 5 以前では使用できない