Автоматическое изменение масштаба приложения на платформе Windows с высоким разрешением?

Я пишу приложение Qt, которое должно работать на Windows с высоким разрешением (192 точек на дюйм вместо 96 точек на дюйм).

К сожалению, фреймворк Qt пока не поддерживает high-dpi (по крайней мере, в Windows), поэтому мое приложение и все его элементы выглядят вдвое меньше, чем должны.

Есть ли способ принудительно / симулировать автоматическое масштабирование таких приложений Windows?

4 ответа

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

Приложение в Windows может принимать один из следующих уровней "DPI Awareness" (из документации Qt):

  • DPI Unaware: этот уровень появился в Windows-Vista. Windows будет делать вид, что приложение работает на стандартном дисплее с разрешением 96 точек на дюйм и разрешением 1920x1080, и соответствующим образом масштабировать приложение. Он предназначен для более старых приложений, предназначенных для дисплеев с низким DPI. Некоторые артефакты могут возникнуть в результате такого масштабирования.
  • System-DPI Aware: этот уровень был введен в Windows-Vista. Он отличается от Per-Monitor DPI Aware только при подключении нескольких мониторов. Windows рассчитает масштаб, подходящий для всех подключенных мониторов.
  • DPI-монитор для каждого монитора: этот уровень появился в Windows 8.1. Windows не выполняет никакого масштабирования вообще.

Также говорится, что:

По умолчанию приложения Qt являются Per-Monitor DPI Aware в Windows 8.1 или System-DPI Aware в более старых версиях Windows. Начиная с Qt 5.4, уровень можно указать, передав параметр в плагин платформы (см. Использование qt.conf):

<application> -platform windows:dpiawareness=0,1,2

Вы можете прочитать больше информации здесь.

В целом, чтобы иметь хороший интерфейс на дисплеях с высоким разрешением, учтите следующее:

  • Используйте последнюю версию Qt
  • Используйте макеты и избегайте фиксированных размеров (если только вы сами не рассчитаете коэффициенты масштабирования)
  • Установите соответствующие настройки DPI в зависимости от потребностей вашего приложения, например, установите Qt::AA_UseHighDpiPixmaps атрибут, если вы работаете с QPainter и растровые изображения, или рассчитайте масштабный коэффициент для корректировки определенных размеров элементов в особых ситуациях.

Qt полностью поддерживает мониторы с высоким DPI с Qt 5.6 и далее через атрибут или переменную окружения (за исключением OS X, где поддержка является нативной). Для метода атрибута используйте:

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); // DPI support

    QApplication app(argc, argv);   
    return app.exec();
}

или установите системную переменную среды:

QT_AUTO_SCREEN_SCALE_FACTOR=1

Я протестировал оба метода на Windows 10 с монитором Surfacebook с высоким разрешением, и результаты масштабируются должным образом, как и ожидалось.

Вот самый быстрый способ решить проблему в Windows.

Рядом с исполняемым файлом создайте файл qt.conf (если его там еще нет) и добавьте следующее:

[Platforms]
WindowsArguments = dpiawareness=0

Окно будет размыто при увеличении. Большим преимуществом этого решения является то, что Windows выполняет масштабирование, а не Qt. Поэтому появление артефактов сводится к минимуму. Кроме того, это может применяться к уже распространенному приложению, поскольку оно не требует перестройки.

Конечно, это не самый приятный результат, но самый быстрый, чтобы в короткие сроки избавить вас от неприятностей, позволяя вам разрабатывать "настоящую" версию с поддержкой DPI без давления.

Я использую Qt 4.8. Во-первых, вы должны использовать макеты. Моей целью было предотвратить изменение размера диалогов, форм и т. Д.

Я добился правильных результатов отображения на разных DPI, поместив этот код в диалоговом конструкторе:

adjustSize();
setFixedSize(size());

Первая строка adjustSize() настроить размер диалога, чтобы соответствовать его содержанию. Вторая линия setFixedSize(size()) исправляет размер диалога после изменения его размера в соответствии с содержимым и не позволяет пользователям изменять его размер. Вы не должны устанавливать размер политики.

Я использую Qt 4.8.7. Это мой код.

static float dpiX = (float)0;
inline int autoDpiSize(int inSize)
{
    if (dpiX == (float)0)
    {
        HDC screen = GetDC(0);
        dpiX = static_cast<float >(GetDeviceCaps(screen, LOGPIXELSX)) / 96.0;
        ReleaseDC(0, screen);
    }
    return dpiX * inSize;
}
someWidget->setFixedHeight(autoDpiSize(30));
Другие вопросы по тегам