15

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

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

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

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

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

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

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

    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 アプリを取得するにはどのようなアプローチを使用すればよいですか?

4

1 に答える 1