Почему мои элементы QML не масштабируются, когда я перемещаю окно на экран с другим разрешением на дюйм?

#qt #windows-10 #qml #dpi

#qt #windows-10 #qml #dpi

Вопрос:

Я использую Windows 10 и Qt 5.15.1. Когда я перемещаю окно приложения QML с экрана с низким разрешением на дюйм (масштаб 100%) на экран с высоким разрешением на дюйм (масштаб 125%), окно масштабируется (изменяет размеры), чтобы использовать больше пикселей, как и ожидалось. Это делает окно одинакового физического размера на обоих экранах.

Однако элементы в окне не масштабируются — они сохраняют одинаковое количество пикселей. Таким образом, все элементы кажутся физически меньшими на экране с высоким разрешением на дюйм.

Как мне масштабировать элементы (до одинакового физического размера) при перемещении окна между экранами с разными DPI? Я хочу, чтобы это происходило со всеми элементами, такими как текст, кнопки, прямоугольники и т.д.

Мой QML:

 import QtQuick 2.12
import QtQuick.Controls 2.12

ApplicationWindow {
    visible: true
    width: 240
    height: 60

    Text {
        text: "Hello World"
        font.pointSize: 14
    }

}
  

Мой Python:

 QtCore.QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
QtCore.QCoreApplication.setAttribute(Qt.AA_UseOpenGLES)

app = QtWidgets.QApplication([])

engine = QtQml.QQmlEngine()
context = QtQml.QQmlContext(engine.rootContext())
designer = QtQml.QQmlComponent(engine, 'main.qml')
designer.create(context)

app.exec_()
  

Фактические и ожидаемые скриншоты текста. Текст не масштабируется, как ожидалось, на экране с высоким разрешением на дюйм.

Комментарии:

1. У вас есть эта строка в вашем main.cpp : QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); ?

Ответ №1:

Я узнал, что Qt округляет масштабирование точек на дюйм до целых чисел по умолчанию. Итак, на моем экране с масштабированием 125% оно было округлено до 100%… таким образом, никаких изменений.

Это поведение можно отключить начиная с Qt 5.14, установив QT_SCALE_FACTOR_ROUNDING_POLICY для переменной среды PassThrough значение . Или в коде:

 QtGui.QGuiApplication.setHighDpiScaleFactorRoundingPolicy(
    Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
  

Кроме того, если вы знаете масштабные коэффициенты ваших мониторов, вы можете указать их напрямую, установив переменную QT_SCREEN_SCALE_FACTORS среды like QT_SCREEN_SCALE_FACTORS=1.25;1 .

Итак, теперь я получаю ожидаемое автоматическое масштабирование на обоих моих экранах.

Правильно масштабируется при 100% и 125%

Комментарии:

1. Приятно знать! Рад, что вы поняли это.

Ответ №2:

На самом деле мне странно, что использование более высокого разрешения на дюйм изменяет размеры вашего приложения. На самом деле это не «масштабирование». Это просто увеличивает окно. И вы не привязываете размер Rectangle к ApplicationWindow , поэтому он остается того же размера. Простой ответ здесь заключается в том, что вы могли бы сделать это:

     Rectangle {
        anchors.fill: parent
        color: "green"
    }
  

Это сохранит прямоугольник того же размера, что и приложение.

Если вы действительно хотите, чтобы все содержимое приложения (включая дочерние элементы прямоугольника) масштабировалось по мере изменения размера ApplicationWindow, то вы могли бы сделать что-то вроде этого:

 ApplicationWindow {
    visible: true
    width: defaultWidth
    height: defaultHeight

    property real defaultWidth: 320
    property real defaultHeight: 240

    Rectangle {
        width: defaultWidth
        height: defaultHeight
        color: "green"

        transform: Scale { 
            xScale: parent.width / defaultWidth
            yScale: parent.height / defaultHeight
        }
    }
}
  

Комментарии:

1. Моя проблема в том, что прямоугольник не масштабируется до того же визуального размера для пользователя. Только окно изменяется должным образом. У текста та же проблема — текст имеет одинаковое количество пикселей как на моих экранах с более высоким, так и с более низким разрешением на дюйм. На экране с высоким разрешением текст должен быть увеличен и использовать больше пикселей, чтобы он имел одинаковый физический размер на обоих экранах.

2. Вы пробовали мой второй пример? Это также должно масштабировать текст.

3. Я не хочу привязывать свои элементы управления к размеру окна. Я просто хочу, чтобы они правильно масштабировались. Предположим, я заменил Rectangle на just Text .

4. Я обновлю свой вопрос, потому что я думаю Rectangle , что это вводит в заблуждение.