Qt Quick Controls 2 Масштабирование

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

Я могу рассчитать коэффициент масштабирования для каждого экрана (т.е. использовать независимые от плотности пиксели Android) и использовать его для определения размеров элементов, полей и т. д. в dp:

ApplicationWindow {
    ...
    property real dp: Screen.pixelDensity * 10 * 2.54 / 160
    Item {
        width: 50*dp
        height: 50*dp
        ...
        Label {
            font.pixelSize: 16*dp
            ...
        }
    }
}

Это работает хорошо, но кажется, что размеры стандартных элементов управления в Qt Quick Controls 2 определены в пикселях, поэтому они не масштабируются. Единственный способ, который я вижу, это переопределить все элементы управления в Qt Quick Controls 2, используя dp вместо пикселей.

Поэтому я ищу способ масштабирования стандартных элементов управления без их переопределения.

UPD1. Я попробовал поддержку High-DPI, это улучшает ситуацию, но все же есть некоторая проблема. Вот некоторые параметры основного экрана (см. описание параметра здесь) из разных устройства до и после применения поддержки высокого разрешения:

// samsung tab t-280 without high dpi support
devicePixelRatio 1
geometry QRect(0,0 800x1280)
logicalDotsPerInch 95.85
physicalDotsPerInch 216.458
physicalSize QSizeF(94, 150) (7')

// samsung tab t-280 with high dpi support
devicePixelRatio 1.33125
geometry QRect(0,0 601x962)
logicalDotsPerInch 72
physicalDotsPerInch 162.648
physicalSize QSizeF(94, 150) (7')


// xiaomi redmi 2 without high dpi support
devicePixelRatio 1
geometry QRect(0,0 720x1280)
logicalDotsPerInch 144
physicalDotsPerInch 315.48
physicalSize QSizeF(58, 103) (4.6')

// xiaomi redmi 2 with high dpi support
devicePixelRatio 2
geometry QRect(0,0 360x640)
logicalDotsPerInch 72
physicalDotsPerInch 157.74
physicalSize QSizeF(58, 103) (4.6')


// macbook pro retina 13' without high dpi support
devicePixelRatio 2
geometry QRect(0,0 1280x800)
logicalDotsPerInch 72
physicalDotsPerInch 113.5
physicalSize QSizeF(286.449, 179.031) (13')

// macbook pro retina 13' with high dpi support
devicePixelRatio 2
geometry QRect(0,0 1280x800)
logicalDotsPerInch 72
physicalDotsPerInch 113.5
physicalSize QSizeF(286.449, 179.031) (13')


// generic 20' display without high dpi support
devicePixelRatio 1
geometry QRect(0,0 1280x1024)
logicalDotsPerInch 72
physicalDotsPerInch 72
physicalSize QSizeF(451.556, 361.244) (22.6')

// generic 20' display with high dpi support
devicePixelRatio 1
geometry QRect(0,0 1280x1024)
logicalDotsPerInch 72
physicalDotsPerInch 72
physicalSize QSizeF(451.556, 361.244) (22.6')


// asus zenbook 13' without high dpi support
devicePixelRatio 1
geometry QRect(0,0 1366x768)
logicalDotsPerInch 96
physicalDotsPerInch 71.9833
physicalSize QSizeF(482, 271) (21.6'!)

// asus zenbook 13' with high dpi support
devicePixelRatio 1
geometry QRect(0,0 1366x768)
logicalDotsPerInch 96
physicalDotsPerInch 71.9833
physicalSize QSizeF(482, 271) (21.6'!)

Похоже, ситуация улучшается для некоторых дисплеев с высоким разрешением (планшет Samsung и телефон Xiaomi). DPI обоих устройств становится около 160 после применения поддержки High-DPI.

Но DPI дисплея Retina и дисплеев с низкой плотностью не меняется, и элементы на экране выглядят больше, чем должны быть. Таким образом, это решает только половину исходной проблемы. Может быть, кто-нибудь знает, как вручную установить коэффициент масштабирования для всех приложений Qt во время выполнения?


person Kamil Zaripov    schedule 08.02.2017    source источник
comment
Я сам спрашивал об этом много лет назад, и в конце концов я использовал подход, аналогичный вашему, с пользовательскими вычислениями падения и глотка... Я до сих пор не думаю, что существует какой-либо стандарт для его сборки в Qt или QML.   -  person Xander    schedule 08.02.2017
comment
Итак, вы переопределяете все элементы Qt Quick Controls 2, используя dip и sip? Или вы вообще не используете Qt Quick Controls 2?   -  person Kamil Zaripov    schedule 08.02.2017
comment
Ну, по сути, да, я использую dp всякий раз, когда я определяю размер или положение визуальных элементов QML, и sp с размером шрифта. Звучит глупо, но это работает и легко реализуемо. Но я использовал глобальный класс C++ и зарегистрировал его как объект контекста QML. Если хотите, я могу опубликовать этот класс в качестве ответа, так как он находится в моем личном репозитории.   -  person Xander    schedule 08.02.2017
comment
Я думаю, что вы не понимаете вопроса. Я также использую dp (dip) и sp (sip) для определения размеров элементов и размеров шрифта, и я не вижу в этом никаких проблем. Проблема, связанная с элементами Qt Quick Controls 2, такими как ComboBox или Кнопка. Размеры этого элемента определяются в пикселях. Вы можете увидеть это здесь. Таким образом, они не масштабируют дисплей от дисплея. И в этом проблема.   -  person Kamil Zaripov    schedule 08.02.2017
comment
Да, я никогда не использовал эти элементы управления в мобильных приложениях, но я думал, что вы все еще можете перезаписать размер, когда размещаете их в своем представлении ?! В любом случае, я, возможно, нашел лучшее решение, если вы используете Qt 5.6+ (см. мой ответ)   -  person Xander    schedule 08.02.2017
comment
Да, вы можете перезаписать размер элементов управления при их размещении, но некоторые элементы управления состоят из подэлементов (например, ComboBox), и вам нужно переписать все размеры всех частей, что почти так же, как перезапись всего элемента управления.   -  person Kamil Zaripov    schedule 08.02.2017
comment
Чтобы установить конкретный коэффициент масштабирования вручную, попробуйте, например, qputenv("QT_SCALE_FACTOR", "3"); в main() перед созданием экземпляра приложения.   -  person jpnurmi    schedule 10.02.2017


Ответы (2)


У меня была та же проблема, и я нашел ответ от jpnurmi наиболее полезным: добавить

qputenv("QT_SCALE_FACTOR", "3"); 

в main() перед созданием экземпляра приложения. Коэффициент 0,75 очень хорошо работал для дисплеев Retina, где элементы управления были слишком большими.

person happygaru    schedule 13.05.2017

Похоже, что начиная с версии Qt 5.6 может быть лучшее решение для независимого от платформы масштабирования.

Поддержка высокого разрешения в Qt Quick Controls 2 https://doc.qt.io/qt-5/qtquickcontrols2-highdpi.html

Надеюсь, это поможет.

person Xander    schedule 08.02.2017
comment
Да, это решает проблему с некоторыми дисплеями с высоким разрешением, но есть проблема (см. UPD1). - person Kamil Zaripov; 08.02.2017