Qt: почему DPI уменьшается при увеличении масштабирования от ОС

У меня есть приложение Qt, и мне нужно адаптировать приложение (увеличение/уменьшение масштаба) по мере изменения масштаба ОС в Настройки экрана.

Я прочитал в Интернете, что:

The standard DPI settings are 100% (96 DPI), 125% (120 DPI), and 150% (144 DPI)

Но я получаю значения ниже DPI при входе в приложение Qt:

Масштаб - Физический DPI X - Физический DPI Y

100% - 158, 159

125% - 158, 159

150% - 79, 79

175% - 79, 79

Итак, согласно приведенным выше значениям, размер текста приложения не имеет разницы для масштаба 100% и 125%. То же поведение применяется для 150% и 175%.

Ниже приведен код Qt, который я использовал:

    #include <QWidget>
    QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QWidget  widget;
    qInfo() << "Hello Qt";
    int dpiX = widget.physicalDpiX();
    int dpiY = widget.physicalDpiY();
    qInfo() << dpiX;
    qInfo() << dpiY;

Кто-нибудь может направить? Я пытаюсь добиться того, чтобы приложение Qt вело себя (изменяло размер приложения/размер шрифта) в зависимости от масштабирования, установленного в Настройки экранаОперационные системы.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
475
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Сначала я предложил использовать QWindow::devicePixelRatio() в этом ответе. Однако, начиная с Qt 5.12, это еще не работает правильно. Qt будет избегать дробных коэффициентов масштабирования из-за ошибка в реализации масштабирования пользовательского интерфейса Qt. Таким образом, для 125% он по-прежнему будет возвращать коэффициент масштабирования 1,0. При 175% он вернет 2,0 вместо 1,75.

Так что пока вам следует вернуться к запросу DPI. Однако запросите логический DPI, нет физический DPI, как вы делаете сейчас. Замените вызовы physicalDpi() функций на вызовы logicalDpi(). Это должно дать вам стандартное разрешение 96/120/144 точек на дюйм, о котором сообщает Microsoft Windows.

Предыдущую часть ответа ниже можно использовать после того, как Qt исправит ошибку.


Предыдущий ответ, применимый после того, как Qt исправит ошибку масштабирования

Запрашивайте коэффициент масштабирования напрямую, не пытайтесь вывести его из DPI. Для этого вы используете QWindow::devicePixelRatio(). При масштабировании 100% это вернет 1.0. При масштабировании 125% он вернет 1,25. И так далее. Поскольку это коэффициент масштабирования, вы используете его как множитель для своих размеров.

Вы должны вызвать devicePixelRatio() в окне, в котором в данный момент находится ваш виджет. Это связано с тем, что разные окна могут быть на разных дисплеях при настройке нескольких мониторов.

Окно, в котором находится виджет, можно получить с помощью QWidget::windowHandle(). Это может вернуть значение null, если виджет не является окном. Поэтому вам, вероятно, следует написать небольшую вспомогательную функцию, которая возвращает правильное DPR (соотношение пикселей устройства) для виджета. Он должен принимать QWidget в качестве аргумента, и если windowHandle() возвращает null для виджета, подниматься по родительскому дереву, вызывая windowHandle() для каждого родителя, пока не найдет первый, который не возвращает null. Тогда вернитесь windowHandle()->devicePixelRatio(). Это будет правильный DPR для использования в этом виджете.

Спасибо за ответ. Я попытался использовать devicePixelRatio() в своем основном приложении, и у меня нет другого виджета в моем приложении. Для 100% и 125% возвращается 1, а для 150% и 175% возвращается 2. EnableHighDpiScaling включен.

CodeZila 09.04.2019 12:27

@CodeZila Да, я обновил ответ. На данный момент вам придется использовать логический DPI, пока Qt не исправит ошибку масштабирования.

Nikos C. 09.04.2019 12:44

Другие вопросы по теме