Qt中的高分辨率及缩放处理

写在前面

使用Qt开发界面客户端,需要考虑不同分辨率及缩放对UI界面的影响,否则会影响整体的交互使用。

问题

高分辨率/缩放设备上图片/图标模糊

若不考虑高分辨及缩放处理,在高分辨率/缩放设备上,软件中的图片、图标可能会出现模糊的问题。

例如:1920 * 1080 100%缩放下的图标如下:

分辨率不变,缩放调整到150%后,图标便会模糊:

高分辨率/缩放设备上控件尺寸问题

若不考虑高分辨及缩放处理,在高分辨率/缩放设备上,软件中的控件可能会由于尺寸放大而出现显示问题。

例如:上面1920 * 1080 100%缩放下软件正常显示如下:

分辨率不变,缩放调整到150%后,控件尺寸会被系统自动放大而出现显示问题:

Qt对高分辨率、缩放的支持

Qt对高分辨率的支持

在Qt中,可以通过布局管理器 + 控件的最大/小尺寸限制 + QSizePolicy 来处理不同分辨率下控件的尺寸问题。

在不考虑缩放的情况下,通过布局管理器 + 控件的最大/小尺寸限制 + QSizePolicy 使界面适应不同分辨率。

1920*1080 100%缩放:

1366 * 768 100%,布局管理器 + 控件的最大/小尺寸限制 + QSizePolicy "组合拳"使得界面自适应分辨率的变化:

Qt对高缩放的支持

在Qt中,可以通过Qt::AA_EnableHighDpiScaling属性,自动适应设备的高缩放设置。

cpp 复制代码
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

设置Qt::AA_EnableHighDpiScaling属性后,调整到高缩放时,使用系统匹配的大小显示。

这种情况称为:缩放敏感性的标准行为。

即,当用户增加系统的缩放设置时,控件尺寸会被系统自动拉大,以便在高分辨率上更容易阅读和操作。

自动拉大的尺寸由系统决定,这时就有可能会超出软件范围,影响UI、甚至交互效果。

如果设置Qt::AA_DisableHighDpiScaling属性,则不应用Qt对高缩放的处理。

cpp 复制代码
QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling);

设置Qt::AA_DisableHighDpiScaling属性后,无论设置多大的缩放,界面都会以默认显示的方式展示,不会被系统自动调整尺寸。

这样的设置的问题是:在高分辨率/缩放的设备上,整个软件界面都会模糊。

处理方案

对高分辨率的处理,使用Qt提供的:布局管理器 + 控件的最大/小尺寸限制 + QSizePolicy 是通用的选择。

对高缩放的处理,可以衍生出以下三种方案:

启用Qt的高DPI属性

即使用缩放敏感性的标准行为,调整到高缩放时,使用系统匹配的大小显示。

cpp 复制代码
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

优点:一行代码搞定,无需另外在代码中做缩放的处理。

缺点:控件尺寸会被系统拉伸,无法精准控制,可能会导致界面变形或被拉伸到屏幕之外。

不启用Qt的高DPI属性

cpp 复制代码
QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling);

优点:一行代码搞定,无需另外在代码中做缩放的处理。

缺点:在高分辨率、缩放设备上运行,整个软件界面可能都会糊掉。

自定义缩放处理

如果希望当系统缩放设置增大时,应用能相应地缩小,以保持相同的视觉效果,可以自定义实现缩放处理。

这通常被称为DPI缩放感知。

注意

这不是标准的缩放敏感性行为。通常,当用户增加系统的缩放设置时,他们期待更大的UI元素,以便在高分辨率上更容易阅读和操作。反过来,如果应用在用户增加系统缩放设置时缩小自己的UI,那么可能会引发用户的迷茫和困扰,因为他们把系统的缩放设置调大,却看到应用的UI反而变小了。

大致原理如下:

在软件初始化时,初始化并维护一个缩放因子。

初始化各个界面控件时,使用该缩放因子重新设置控件的尺寸。

当系统调整缩放时,更新缩放因子,并重新应用更新后的缩放因子到各个界面的控件上(重新设置控件尺寸)。

通用处理方案

通过以下两个实际案例,可以得知通用的处理方式:

UI以小尺寸设计,向上兼容,兼容方式可选启用或不启用高DPI属性,一般选择启用高DPI属性来避免界面模糊。

使用布局管理器自动处理分辨率变化,使用Qt的高DPI属性处理缩放变化。

方案示例

可以参考一些成熟的Windows客户端的处理方案

Windows飞书客户端

1920 * 1080分辨率 100%缩放,显示窗口尺寸: 1276 * 660:

调整为150%缩放后,计算推断尺寸:1276 * 1.5 = 1914, 660 * 1.5 = 990,实际尺寸:1920*1000

MarkText

1920 * 1080分辨率 100%缩放,显示窗口尺寸:1190 * 679:

调整为150%,计算推断尺寸:1190 * 1.5 = 1785, 679 * 1.5 = 1018,缩放后实际尺寸:1784*1004

总结

本文以Qt客户端开发中遇到的高分辨率、缩放问题,引出Qt对高分辨率、缩放的支持,并衍生出三种对高分辨率、缩放问题的处理方式。

最后参考程序的Windows客户端程序,总结了一种通用的高分辨率、缩放处理方案。

当然,也得根据应用场景、实际需求来选择合适的处理方式。

相关推荐
c4fx4 分钟前
Delphi5利用DLL实现窗体的重用
开发语言·delphi·dll
鸽芷咕27 分钟前
【Python报错已解决】ModuleNotFoundError: No module named ‘paddle‘
开发语言·python·机器学习·bug·paddle
Jhxbdks37 分钟前
C语言中的一些小知识(二)
c语言·开发语言·笔记
java66666888837 分钟前
如何在Java中实现高效的对象映射:Dozer与MapStruct的比较与优化
java·开发语言
Violet永存38 分钟前
源码分析:LinkedList
java·开发语言
代码雕刻家40 分钟前
数据结构-3.1.栈的基本概念
c语言·开发语言·数据结构
Fan_web41 分钟前
JavaScript高级——闭包应用-自定义js模块
开发语言·前端·javascript·css·html
梦想科研社1 小时前
【无人机设计与控制】四旋翼无人机俯仰姿态保持模糊PID控制(带说明报告)
开发语言·算法·数学建模·matlab·无人机
风等雨归期1 小时前
【python】【绘制小程序】动态爱心绘制
开发语言·python·小程序
千穹凌帝1 小时前
SpinalHDL之结构(二)
开发语言·前端·fpga开发