新しいQt5.7 +高DPI /モニターDPI対応アプリケーションの開発にアプローチする方法は?

michnovka

Qtの公式ドキュメントと、Qtでの高DPIサポートに関するStackOverflowに関する多くの記事と質問を読みましたそれらはすべて、古いアプリケーションを移植し、可能な限り変更を加えずに機能させることに重点を置いています。

しかし、モニターごとのDPI対応アプリをサポートすることを目的として、まったく新しいアプリケーションを開始する場合、最善のアプローチは何ですか?

私が正しく理解していれば、それQt::AA_EnableHighDpiScalingは私が望んでいることとは正反対です。実際にHighDpiScalingを無効にして、実行時にすべてのディメンションを手動で計算する必要がありますか?

提案の多くは、サイズをまったく使用せず、フローティングレイアウトを使用することを示しています。しかし、多くの場合、少なくとも最小の幅および/または最小の高さが存在することが望まれます。Qt Designerでは絶対ピクセルでしか値を入力できないので、正しいアプローチは何ですか?モニターの解像度が変更された場合、ディメンションを再計算するためのコードをどこに配置する必要がありますか?

それとも、自動スケーリングを使用する必要がありますか?

以前のQtアプリからの私のソリューション(十分にテストされていません)

HighDPIサポートを追加しようとした古いアプリの1つで、このアプローチを使用しました。DOMのすべての子を一覧表示し、一定の比率で1つずつサイズを変更します。比率= 1は、QtDesignerで指定したものと同じ寸法を生成します。

    void resizeWidgets(MyApp & qw, qreal mratio)
    {

        // ratio to calculate correct sizing
        qreal mratio_bak = mratio;

        if(MyApp::m_ratio != 0)
            mratio /= MyApp::m_ratio;

        // this all was done so that if its called 2 times with ratio = 2, total is not 4 but still just 2 (ratio is absolute)
        MyApp::m_ratio = mratio_bak;

        QLayout * ql = qw.layout();

        if (ql == NULL)
            return;

        QWidget * pw = ql->parentWidget();

        if (pw == NULL)
            return;

        QList<QLayout *> layouts;

        foreach(QWidget *w, pw->findChildren<QWidget*>())
        {
            QRect g = w->geometry();

            w->setMinimumSize(w->minimumWidth() * mratio, w->minimumHeight() * mratio);
            w->setMaximumSize(w->maximumWidth() * mratio, w->maximumHeight() * mratio);

            w->resize(w->width() * mratio, w->height() * mratio);
            w->move(QPoint(g.x() * mratio, g.y() * mratio));
            
        }

        foreach(QLayout *l, pw->findChildren<QLayout*>())
        {
            if(l != NULL && !(l->objectName().isEmpty()))
                layouts.append(l);
        }
        
        foreach(QLayout *l, layouts) {
            QMargins m = l->contentsMargins();

            m.setBottom(m.bottom() * mratio);
            m.setTop(m.top() * mratio);
            m.setLeft(m.left() * mratio);
            m.setRight(m.right() * mratio);

            l->setContentsMargins(m);

            l->setSpacing(l->spacing() * mratio);

            if (l->inherits("QGridLayout")) {
                QGridLayout* gl = ((QGridLayout*)l);

                gl->setHorizontalSpacing(gl->horizontalSpacing() * mratio);
                gl->setVerticalSpacing(gl->verticalSpacing() * mratio);
            }

        }
        
        QMargins m = qw.contentsMargins();

        m.setBottom(m.bottom() * mratio);
        m.setTop(m.top() * mratio);
        m.setLeft(m.left() * mratio);
        m.setRight(m.right() * mratio);

        // resize accordingly main window
        qw.resize(qw.width() * mratio, qw.height() * mratio);
        qw.setContentsMargins(m);
        qw.adjustSize();
    }

これはメインから呼び出されます:

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

    QApplication a(argc, argv);
    MyApp w;

    // gets DPI
    qreal dpi = a.primaryScreen()->logicalDotsPerInch();

    MyApp::resizeWidgets(w, dpi / MyApp::refDpi);

    w.show();

    return a.exec();
}

これは良い解決策ではないと思います。新しく始めて、コードを最新のQt標準に完全にカスタマイズできることを考えると、HighDPIアプリを入手するにはどのようなアプローチを使用する必要がありますか?

アレクサンダーV

モニターごとのDPI認識をサポートすることを目的として、まったく新しいアプリケーションを開始する場合、最善のアプローチは何ですか?

モニターごとのDPI対応モードでの自動スケーリングをQtに依存していません。少なくともQt::AA_EnableHighDpiScalingセット付きのQt5.7ベースのアプリはそれを行わず、「高DPIスケーリング」はピクセル密度に関係なくより正確な描画です。

また、モニターごとのDPI対応モードを呼び出すにQt.confは、実行可能ファイルを投影するのと同じディレクトリにあるファイルを変更する必要があります。

[Platforms]
# 1 - for System DPI Aware
# 2 - for Per Monitor DPI Aware
WindowsArguments = dpiawareness=2

# May need to define this section as well
#[Paths]
#Prefix=.

私が正しく理解していれば、Qt :: AA_EnableHighDpiScalingは私が望むものとは正反対です。実際にHighDpiScalingを無効にして、実行時にすべてのディメンションを手動で計算する必要がありますか?

いいえ、それは反対ではなく、別のことです。バグなしとしてクローズされたQtバグがいくつかあります。QTBUG-55449QTBUG-55510で、機能の背後にある意図を示しています。ところで、QTBUG-55510があり、修正せずにQt DPI認識を設定するためのプログラムによる回避策qt.confが提供されています(新しいQtバージョンでは通知なしにインターフェイスを変更する「プライベート」Qt実装クラスを使用するため、独自の裁量で使用してください)。

また、モニターごとのDPI対応モードでスケーリングを行うための正しいアプローチを表現しました。残念ながら、当時は選択肢があまりないことを除けば。ただし、あるモニターから別のモニターに移動するときにウィンドウスケーリングのイベント処理を支援するプログラム的な方法があります。resizeWidgetこの質問の先頭にある(1つ、多くはない)のようなメソッドは、(Windows)のようなものを使用して呼び出す必要があります。

// we assume MainWindow is the widget dragged from one monitor to another
bool MainWindow::nativeEvent(const QByteArray& eventType, void* message, long* result)
{
   MSG* pMsg = reinterpret_cast<MSG*>(message);

   switch (pMsg->message)
   {
      case WM_DPICHANGED:
         // parameters TBD but mind that 'last' DPI is in
         // LOWORD(pMsg->wParam) and you need to detect current
         resizeWidget(monitorRatio());
         break;

これは非常に困難で面倒な方法であり、ユーザーがモードを選択してアプリプロセスを再開できるようにすることで、アプリがシステムとモニターごとのDPI対応モードを切り替えることができるようにしました(QTBUG-55510修正qt.confまたは回避策を実行します)。アプリの起動)。Qt社が、ウィジェットの自動スケーリングを備えたモニターごとのDPI対応モードの必要性を認識していることを願っています。なぜそれが必要なのか(?)は別の質問です。私の場合、スケーリングされるはずの独自のアプリウィジェットキャンバス内にモニターごとのレンダリングがあります。

最初に、@ selbieからのこの質問へのコメントを読んで、アプリの起動中にQT_SCREEN_SCALE_FACTORSを設定しようとする方法があるかもしれないことに気付きました。

QT_SCREEN_SCALE_FACTORS [list]は、各画面の倍率を指定します。これにより、ポイントサイズのフォントのサイズは変更されません。この環境変数は、主にデバッグ、または誤ったEDID情報(拡張表示識別データ)を持つモニターを回避するために役立ちます。

次に、複数の画面要素を適用する方法についてQtブログ読み、4Kが最初にリストされている(メイン)4Kおよび1080pモニターに対して以下を実行しようとしました。

qputenv("QT_SCREEN_SCALE_FACTORS", "2;1");

これは少し役立ちます。ほぼ正しいレンダリングですが、QTBUG-55449とほぼ同じように、ウィンドウをあるモニターから別のモニターに移動するときにウィンドウサイズに欠陥が生じます。お客様が現在のアプリの動作をバグと見なす場合は、WM_DPICHANGED+QT_SCREEN_SCALE_FACTORSアプローチを採用すると思います(システムDPI対応を介してすべてのモニターDPIに対して同じベースを作成します)。それでも、Qtのすぐに使用できるソリューションはまだありません。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

高DPI対応アプリケーションでランタイムが作成したTButtonコントロールは、モニターのDPIに合わせて拡張されません

分類Dev

高dpiモニターと低dpiモニターのスケーリングを個別に設定するにはどうすればよいですか?

分類Dev

高dpiモニターと低dpiモニターのスケーリングを個別に設定するにはどうすればよいですか?

分類Dev

モニターごとのDPI対応アプリは、VS2013でシステムDPI対応として実行されます

分類Dev

高DPIコンピューターでJAVAアプリケーションプロジェクト(Chromis POS)の解像度を調整します

分類Dev

Windows 7デュアルモニター、アプリケーションを開くときに、アプリケーションのUIを表示するモニターを制御するにはどうすればよいですか?

分類Dev

DPI非対応のアプリケーションがスケーリング/仮想化されているかどうかを検出します

分類Dev

子ウィンドウは、モニターごとのアプリケーションで親と同じDPIを持っていますか?

分類Dev

私のWPFアプリは、モニターごとのdpi対応です。私はそれを期待していなかったのですか?

分類Dev

高DPIディスプレイでアップスケールされたJavaアプリを実行するにはどうすればよいですか?

分類Dev

高DPIモード用のPNGアイコンを使用したTImageListのスケーリング

分類Dev

Qt5で高DPIの画像を拡大縮小する最良の方法は何ですか?

分類Dev

wxWidgetsアプリがより高いdpiでサイズをスケーリングしないようにする

分類Dev

Javaでスケーラビリティの高いWebアプリケーションを開発するには、何をする必要がありますか?

分類Dev

並行性の高いアプリケーションにグローバルカウンターを実装する最良の方法は?

分類Dev

カスタムスケーリングを使用したRDP接続(高DPI)

分類Dev

Unity 7ランチャーアプリケーションに対応するパッケージバージョンを取得するにはどうすればよいですか?

分類Dev

プログラムで、またはマニフェスト(MinGW)を使用して、「高DPIスケーリングを上書きする」を「システム(拡張)」に設定する

分類Dev

ダウンロードアプリケーションを使用して、低dpiデバイスに写真のみをダウンロードさせるにはどうすればよいですか?

分類Dev

Qt 5.6で高dpiで鮮明なUIを取得する方法

分類Dev

Qt5.6:高DPIサポートとOpenGL(OpenSceneGraph)

分類Dev

CSSだけを使用して50%のスケーリングで高DPI画像を表示する

分類Dev

Windows8.1をサポートするアプリケーションでのモニターごとの高DPIサポートのための非クライアント領域のスケーリング

分類Dev

最大化時にセカンダリモニターでwpfアプリケーションの画面の高さを設定します

分類Dev

高DPI画面のJavaベースのアプリケーションのスケーリングを修正

分類Dev

高さのアニメーション中にタップジェスチャが応答しない

分類Dev

Delphiは実行時に高dpiを変更します

分類Dev

Windows7のQt5でアプリケーションをコンパイルできません

分類Dev

高 dpi ディスプレイ上の絶対配置要素がずれている

Related 関連記事

  1. 1

    高DPI対応アプリケーションでランタイムが作成したTButtonコントロールは、モニターのDPIに合わせて拡張されません

  2. 2

    高dpiモニターと低dpiモニターのスケーリングを個別に設定するにはどうすればよいですか?

  3. 3

    高dpiモニターと低dpiモニターのスケーリングを個別に設定するにはどうすればよいですか?

  4. 4

    モニターごとのDPI対応アプリは、VS2013でシステムDPI対応として実行されます

  5. 5

    高DPIコンピューターでJAVAアプリケーションプロジェクト(Chromis POS)の解像度を調整します

  6. 6

    Windows 7デュアルモニター、アプリケーションを開くときに、アプリケーションのUIを表示するモニターを制御するにはどうすればよいですか?

  7. 7

    DPI非対応のアプリケーションがスケーリング/仮想化されているかどうかを検出します

  8. 8

    子ウィンドウは、モニターごとのアプリケーションで親と同じDPIを持っていますか?

  9. 9

    私のWPFアプリは、モニターごとのdpi対応です。私はそれを期待していなかったのですか?

  10. 10

    高DPIディスプレイでアップスケールされたJavaアプリを実行するにはどうすればよいですか?

  11. 11

    高DPIモード用のPNGアイコンを使用したTImageListのスケーリング

  12. 12

    Qt5で高DPIの画像を拡大縮小する最良の方法は何ですか?

  13. 13

    wxWidgetsアプリがより高いdpiでサイズをスケーリングしないようにする

  14. 14

    Javaでスケーラビリティの高いWebアプリケーションを開発するには、何をする必要がありますか?

  15. 15

    並行性の高いアプリケーションにグローバルカウンターを実装する最良の方法は?

  16. 16

    カスタムスケーリングを使用したRDP接続(高DPI)

  17. 17

    Unity 7ランチャーアプリケーションに対応するパッケージバージョンを取得するにはどうすればよいですか?

  18. 18

    プログラムで、またはマニフェスト(MinGW)を使用して、「高DPIスケーリングを上書きする」を「システム(拡張)」に設定する

  19. 19

    ダウンロードアプリケーションを使用して、低dpiデバイスに写真のみをダウンロードさせるにはどうすればよいですか?

  20. 20

    Qt 5.6で高dpiで鮮明なUIを取得する方法

  21. 21

    Qt5.6:高DPIサポートとOpenGL(OpenSceneGraph)

  22. 22

    CSSだけを使用して50%のスケーリングで高DPI画像を表示する

  23. 23

    Windows8.1をサポートするアプリケーションでのモニターごとの高DPIサポートのための非クライアント領域のスケーリング

  24. 24

    最大化時にセカンダリモニターでwpfアプリケーションの画面の高さを設定します

  25. 25

    高DPI画面のJavaベースのアプリケーションのスケーリングを修正

  26. 26

    高さのアニメーション中にタップジェスチャが応答しない

  27. 27

    Delphiは実行時に高dpiを変更します

  28. 28

    Windows7のQt5でアプリケーションをコンパイルできません

  29. 29

    高 dpi ディスプレイ上の絶対配置要素がずれている

ホットタグ

アーカイブ