Автоматическое изменение масштаба приложения на платформе 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));