Qt GUIプログラミング:QWindow::devicePixelRatio() を使って高DPIディスプレイに最適なUIを構築しよう


Qt GUI における QWindow::devicePixelRatio() 関数は、デバイスピクセル比を取得するために使用されます。デバイスピクセル比とは、画面上の物理ピクセルと論理ピクセル間の比率を表す値です。この値は、高解像度ディスプレイや Retina ディスプレイなどの高 DPI デバイスで特に重要となります。

QWindow::devicePixelRatio() の役割

QWindow::devicePixelRatio() 関数は、以下の役割を果たします。

  • アイコンや画像のサイズ調整
    アイコンや画像も論理ピクセル単位で指定されます。QWindow::devicePixelRatio() を使用して、アイコンや画像のサイズをデバイスピクセル単位に変換することで、高 DPI ディスプレイでも適切なサイズで表示することができます。
  • フォントサイズの調整
    高 DPI ディスプレイでは、フォントサイズも論理ピクセル単位で指定されます。QWindow::devicePixelRatio() を使用して、フォントサイズをデバイスピクセル単位に変換することで、高 DPI ディスプレイでも適切なサイズでフォントを表示することができます。
  • 高 DPI ディスプレイでの UI 要素のスケーリング
    高 DPI ディスプレイでは、論理ピクセルと物理ピクセルの比率が大きくなります。QWindow::devicePixelRatio() を使用してこの比率を取得することで、UI 要素を適切なサイズにスケーリングすることができます。

QWindow::devicePixelRatio() の使用方法

QWindow::devicePixelRatio() 関数は、以下の方法で使用することができます。

qreal devicePixelRatio = window->devicePixelRatio();

このコードは、現在のウィンドウのデバイスピクセル比を取得します。取得したデバイスピクセル比は、UI 要素のスケーリング、フォントサイズの調整、アイコンや画像のサイズ調整などに使用することができます。

例:ボタンのスケーリング

以下のコードは、ボタンのサイズをデバイスピクセル比に基づいてスケーリングする例です。

QPushButton *button = new QPushButton("ボタン");

qreal devicePixelRatio = button->window()->devicePixelRatio();

button->resize(button->size() * devicePixelRatio);

このコードは、まず新しい QPushButton オブジェクトを作成します。次に、現在のウィンドウのデバイスピクセル比を取得します。最後に、ボタンのサイズをデバイスピクセル比で乗算することで、ボタンを適切なサイズにスケーリングします。



例1:ボタンのスケーリング

この例では、ボタンのサイズをデバイスピクセル比に基づいてスケーリングします。

QPushButton *button = new QPushButton("ボタン");

qreal devicePixelRatio = button->window()->devicePixelRatio();

button->resize(button->size() * devicePixelRatio);

例2:フォントサイズの調整

この例では、フォントサイズをデバイスピクセル比に基づいて調整します。

QLabel *label = new QLabel("ラベル");

qreal devicePixelRatio = label->window()->devicePixelRatio();

QFont font = label->font();
font.setPointSize(font.pointSize() * devicePixelRatio);
label->setFont(font);

例3:アイコンのサイズ調整

この例では、アイコンのサイズをデバイスピクセル比に基づいて調整します。

QLabel *label = new QLabel;
label->setPixmap(QPixmap("icon.png"));

qreal devicePixelRatio = label->window()->devicePixelRatio();

QSize iconSize = label->pixmap()->size();
iconSize *= devicePixelRatio;
label->setPixmap(label->pixmap()->scaled(iconSize, Qt::KeepAspectRatio));

これらの例は、QWindow::devicePixelRatio() 関数をどのように使用して、高 DPI ディスプレイでの UI 要素を適切にスケーリングできるかを示しています。

上記以外にも、QWindow::devicePixelRatio() 関数は、以下の用途に使用することができます。

  • カスタム描画
    カスタム描画を行う際に、デバイスピクセル比を使用して、描画するオブジェクトのサイズや位置を調整することができます。
  • ウィンドウ全体のスケーリング
    ウィンドウ全体のサイズをデバイスピクセル比で乗算することで、ウィンドウを適切なサイズにスケーリングすることができます。


代替方法

以下に、QWindow::devicePixelRatio() の代替方法として検討できるいくつかの方法をご紹介します。

QScreen::devicePixelRatio()

QScreen::devicePixelRatio() 関数は、指定されたスクリーンのデバイスピクセル比を取得します。この関数は、ウィンドウに関連付けられたスクリーンを取得することで使用することができます。

QScreen *screen = QGuiApplication::primaryScreen();
qreal devicePixelRatio = screen->devicePixelRatio();

QApplication::screens()

QApplication::screens() 関数は、すべてのスクリーンのリストを取得します。このリストをループして、各スクリーンのデバイスピクセル比を取得することができます。

QList<QScreen *> screens = QApplication::screens();

for (QScreen *screen : screens) {
  qreal devicePixelRatio = screen->devicePixelRatio();
  // ...
}

QPaintDevice::devicePixelRatio()

QPaintDevice::devicePixelRatio() 関数は、ペイントデバイスのデバイスピクセル比を取得します。この関数は、QPainterQImage などのペイントデバイスオブジェクトで使用することができます。

QPainter painter(widget);
qreal devicePixelRatio = painter.device()->devicePixelRatio();

// ...

ローカルスケーリングファクタ

ローカルスケーリングファクタは、特定のウィジェットやコンポーネントにのみ適用されるスケーリングファクタです。これは、QWindow::devicePixelRatio() を使用してグローバルなスケーリングファクタを設定するよりも、よりきめ細かな制御が必要な場合に役立ちます。

widget->setContentsMargins(10 * devicePixelRatio, 10 * devicePixelRatio,
                          10 * devicePixelRatio, 10 * devicePixelRatio);

カスタムスケーリングロジック

独自のスケーリングロジックを実装することもできます。これは、複雑なレイアウトやアニメーションを処理する場合に役立ちます。

最適な方法の選択

どの代替方法が最適かは、状況によって異なります。一般的には、以下の点を考慮する必要があります。

  • パフォーマンス
    処理速度への影響。
  • 制御のレベル
    どの程度きめ細かな制御が必要か。
  • スケーリングの範囲
    グローバルなスケーリングが必要か、特定のウィジェットやコンポーネントのみをスケーリングする必要があるか。

QWindow::devicePixelRatio() は、高 DPI ディスプレイでの UI 要素のスケーリングに便利な関数ですが、状況によっては代替方法の方が適切な場合があります。上記で紹介した代替方法を検討することで、より柔軟で効率的なスケーリングを実現することができます。

  • Qt 6 以降では、QWindow::contentScaleFactor() 関数を使用して、ウィンドウ全体のスケーリングファクタを設定することができます。
  • 上記以外にも、QPainter::scale()QFont::setPointSizeF() などの関数を使用してスケーリングを行うこともできます。