与标准DPI显示器相比,高DPI显示器增加了像素密度。
像素密度以每英寸点数(DPI)或每英寸像素(PPI)来衡量,由显示像素的数量和它们的大小决定。因此,单独的像素数量不足以确定显示器是否属于高dpi类别。
4K显示器有固定的像素数(约8米),但它的DPI在185(23英寸)和110(40英寸)之间变化。前者是标准96 DPI桌面分辨率的两倍左右;后者仅略高于这个分辨率。
高DPI的挑战
高DPI显示给现有应用带来了一些挑战:
- 使用固定坐标的UI设计的应用程序看起来很小
- 以点为单位指定字体大小和以像素为单位指定其他大小的组合特别成问题,因为点与显示器的分辨率无关。例如,假设我们有一个40x20像素的帧围绕文本"hello"。如果我们使用12pt字体,它在低分辨率显示器上看起来应该是正确的。但是,在高DPI显示器上,帧会太小,导致文本被剪切。
- 应用程序必须适应用户拥有不同分辨率的多个显示器的情况
- 例如,用户可能在图像编辑器的文档窗口中使用4K显示器,但在工具箱中使用低分辨率显示器。
传统上,为了支持高DPI, Qt会自动缩放字体,并提供一个DPI值,应用程序代码可以使用该值来缩放UI的其余部分。
系统级别的高DPI支持
Qt支持高DPI模式,其中主坐标系统是虚拟化的,与显示像素密度无关。有些操作系统,如macOS和iOS实现了这种模式。此外,如果某个操作系统不支持这种模式,Qt也有一个备用实现。
现在,几何形状是在设备无关像素中指定的。这包括组件和项目的几何形状、事件的几何形状、桌面、窗口和屏幕的几何形状,以及动画的速度。输出以设备像素的形式呈现,对应于显示分辨率。devicePixelRatio是设备无关像素与设备像素坐标系之间的比率。
通常,大多数应用程序都使用独立于设备的像素;除了OpenGL和光栅图形的代码。
操作系统支持
qt支持的操作系统提供以下高DPI显示:
macOS和iOS
苹果平台在操作系统中实现了可扩展和协调系统虚拟化。通常不需要特殊配置。
在macOS上,通过Info.plist文件设置启用高dpi支持;因此,请确保这些设置存在
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSHighResolutionCapable</key>
<string>True</string>
最新版本的qmake使用NSPrincipalClass key生成Info.plist文件;这是足够的,因为NSHighResolutionCapable默认是true。
注意:macOS和iOS都可能应用进一步的虚拟化,这样设备像素不再对应于1:1的显示像素。这发生在iPhone 6+和macOS上,配置了"显示缩放"功能。
Microsoft Windows
缩放比例
用户可以从控制面板或通过上下文菜单选择比例因子。这是通过使查询系统指标的函数为标准字体大小、窗口边框大小等返回不同的值来实现的。它不执行任何实际的缩放
DPI感知
Windows上的应用程序可以假设以下级别之一的"DPI感知"
DPI Awareness Level | Meaning |
---|---|
DPI Unaware | 这个级别是在Windows Vista中引入的。对于应用程序,Windows假装它在1920x1080的96 DPI标准显示器上运行,并相应地缩放应用程序。它旨在适应为低DPI显示设计的旧应用程序。这种类型的缩放可能会导致一些工件。 |
System-DPI Aware | 这个级别是在Windows Vista中引入的。只有在连接多个监视器时,它才与逐监视器DPI感知不同。Windows计算出一个适用于所有连接的显示器的比例。 |
Per-Monitor DPI Aware | 该级别在Windows 8.1中引入。Windows根本不执行任何缩放。 |
默认情况下,Qt应用程序在Windows 8.1上被设置为逐监视器DPI感知或在旧版本的Windows上被设置为系统DPI感知。从Qt 5.4开始,这个级别可以通过平台插件的参数来指定:
<application> -platform windows:dpiawareness=0,1,2
Using qt.conf | Qt 5.15有关详细资料请参阅 Using qt.conf.
Qt高DPI支持
Qt提供了以下方法来处理应用程序中的高DPI支持。
- 能够提供高分辨率的像素图或插图。有关详细信息,请参见Drawing High Resolution Versions of Pixmaps and Images.
- Qt 5.6支持传统应用的跨平台高dpi扩展,类似于macOS原生的扩展。这允许为低DPI屏幕编写的应用程序在高DPI设备上不变地运行。此功能是可选的,可以使用以下环境变量启用:
- QT_AUTO_SCREEN_SCALE_FACTOR[布尔值]启用自动缩放,基于显示器的像素密度。这不会改变点大小字体的大小,因为点是一个物理测量单位。多个屏幕可能会得到不同的比例因子。
- QT_SCALE_FACTOR [numeric]定义了整个应用程序的全局缩放因子,包括点大小的字体。
- QT_SCREEN_SCALE_FACTORS [list]指定每个屏幕的缩放因子。这不会改变点大小字体的大小。环境变量主要用于调试,或处理具有错误EDID信息(扩展显示标识数据)的监视器。
- 格式可以是一个分号分隔的比例因子列表,其顺序与QGuiApplication::screens()相同,也可以是一个分号分隔的name=value对列表,其中name与QScreen::name()相同。
虽然macOS风格完全支持高dpi,但Windows桌面风格目前在某些比例因素上有一些限制。在这些情况下,考虑使用Fusion样式,它在所有情况下都支持高dpi。
虽然macOS风格完全支持高dpi,但Windows桌面风格目前在某些比例因素上有一些限制。在这些情况下,考虑使用Fusion样式,它在所有情况下都支持高dpi。
注意:非整数缩放因子可能导致显著的缩放/绘制伪影。
- Qt::AA_EnableHighDpiScaling应用程序属性在Qt 5.6中引入,可以根据显示器的像素密度自动缩放。
- Qt 5.6中引入的Qt::AA_DisableHighDpiScaling应用属性可以关闭所有的扩展功能。这适用于需要实际窗口系统坐标的应用程序,而无需考虑环境变量。该属性的优先级高于Qt::AA_EnableHighDpiScaling。
- QT_ENABLE_HIGHDPI_SCALING环境变量在Qt 5.14中引入,可以根据显示器的像素密度自动缩放。替换QT_AUTO_SCREEN_SCALE_FACTOR。
- Qt 5.14中引入的QT_SCALE_FACTOR_ROUNDING_POLICY环境变量和QGuiApplication::highDpiScaleFactorRoundingPolicy API可以控制设备像素比是否以及如何四舍五入到最近的整数。这与窗口150%缩放等配置相关。取值包括:Round、Ceil、Floor、RoundPreferFloor、PassThrough。有关选项的完整描述,请参阅Qt::HighDpiScaleFactorRoundingPolicy枚举文档。
- 在Qt 5.4中,通过QT_DEVICE_PIXEL_RATIO环境变量引入了高DPI缩放的实验实现,您可以设置为数字缩放因子或自动。这个变量在Qt 5.6中已弃用。
转移现有应用程序
为了让一个为低DPI值设计的应用程序快速在高分辨率显示器上运行,请考虑以下之一:
- 让应用程序在Windows上作为DPI自动运行,将QT_AUTO_SCREEN_SCALE_FACTOR环境变量设置为1。
然而,这些选项可能会导致一些缩放或绘制工件。
从长远来看,应用程序应该适应运行而无需修改:
- 始终使用QPainter绘图API的qreal版本。
- 窗口和对话框相对于相应的屏幕大小。
- 将布局和绘图代码中硬编码的尺寸替换为根据字体度量或屏幕大小计算的值。
高DPI术语表
Term | Definition |
---|---|
Device Independent Pixels | 应用程序使用的像素(用户空间),取决于操作系统或Qt的缩放。 |
Device Pixels | 显示设备的像素。 |
Device Pixel Ratio | 操作系统或Qt应用的比例因子。 |
Logical DPI | 用于将以点为单位定义的字体大小转换为以像素为单位的字体大小的分辨率。标准值是96、128、...192. |
Physical DPI | 显示器的大小除以像素数得到的物理分辨率。 |
User Space | 应用程序在设备无关像素中使用的坐标空间。 |