高DPI
高DPI显示器——也称为视网膜显示器——是指在物理尺寸(毫米)相对于分辨率(像素)情况下具有高分辨率的显示器,从而实现高像素密度或高每英寸点数(DPI)。增加的分辨率用于在屏幕上提供更详细的内容(更平滑的文本、更详细的图标),而不是更多的内容(更多的窗口、更大的窗口尺寸)。
Qt支持所有平台上的高DPI显示器,并提供了统一的应用程序编程接口(API),以抽象处理任何平台差异。Qt在使用更高层的API,如Qt Widgets和Qt Quick时,会自动考虑显示分辨率,而应用程序只需要提供高分辨率的资源,如图片和图标。平台用户首选项的变化也会自动捕获。
更底层的图形绘制(如OpenGL代码)需要了解高DPI,但可以使用跨平台的Qt API来了解平台的显示分辨率。
概念模型
Qt使用一个模型,其中应用程序坐标系与显示设备分辨率无关。应用程序在设备无关像素中运行,然后通过一个称为设备像素比的比例因子映射到显示器的物理像素。比例因子表示为一个浮点数,例如1.0
或2.0
,或者非正式地表示为1x
和2x
。
例如,创建一个QWindow或QWidget,将其大小设置为200x200,将覆盖普通密度显示器(设备像素比为1.0)上的200x200显示像素,但在高密度显示器(设备像素比为2.0)上覆盖400x400像素。
这个模型适用于几乎所有高级Qt GUI、Widgets和Quick API中的单元,包括小部件和项几何形状、事件几何形状、桌面、窗口和屏幕几何形状,以及动画速度。
注意:这个模型不处理UI类之间的差异,例如触摸目标与鼠标目标的大小。
绘制
Qt在使用绘制API(如QPainter)或渲染Qt Quick中的图形原语或文本时,会自动利用高DPI显示的更高密度。
因此,应用程序可以在单个统一的坐标系统中运行,而无需考虑应用程序运行的潜在显示密度。
然而,在使用低级绘图API,例如OpenGL时,应用程序需要考虑显示器设备像素比。这适用于每个窗口,例如通过QWindow::devicePixelRatio()(在显示器之间移动时跟踪窗口的设备像素比)或者适用于每个显示器,例如QScreen::devicePixelRatio()。
图像缓冲区,如QImage和QPixmap代表原始像素,因此不操作早期提到的设备无关坐标系统。一个大小为400x400的QImage,在设备像素比为2.0的情况下,将适合高密度(2x)显示器上的200x200 QWindow,或者如果目标是普通密度(1x)显示器,将在绘制期间自动缩小到200x200。有关更多详细信息,请参阅绘制位图和图像的高分辨率版本。
图像资源
为了利用高DPI显示增加的像素密度,应用程序还应包括静态图像资源的高DPI版本。这通过为高密度资源使用特殊的命名约定实现,例如[email protected]
,并将正常密度图像和高密度图像加载到QIcon中。Qt将自动在运行时为目标显示器选择最佳表示。有关更多详细信息,请参阅高DPI图标。
设备无关屏幕几何形状
Qt应用程序通常在设备无关像素中运行。这包括报告给应用程序的窗口和屏幕几何形状。
这意味着QScreen::geometry()可能不会返回屏幕的物理像素计数,或者操作系统报告的像素大小。这对于虚拟桌面几何具有重要意义。
现代桌面操作系统通常为所有连接的屏幕创建一个共享坐标系统,并允许用户将屏幕定位以匹配他们的物理屏幕设置,通常通过配置对话框完成。如果在与Qt的设备无关像素相似的坐标系统中进行此定位(如macOS),则QScreen几何形状将匹配原生屏幕布局。如果定位是在屏幕物理像素中进行(如Windows),则Qt处理屏幕几何形状可能会在虚拟桌面几何形状中引入未被任何屏幕使用的“间隙”。
具体来说,Qt会调整屏幕大小(导致“较小”的屏幕,对于正的缩放因子),但不会更改屏幕位置。这将产生像岛屿一样的虚拟桌面几何形状。
应用程序代码不应假设一个屏幕和其相邻且在外的位置是相邻屏幕上的有效位置。相反,应使用QGuiApplication::screens()获取屏幕列表,并用该列表来推理可用的屏幕几何形状。
配置
作为最终用户,您可能希望调整DPI或缩放设置以匹配显示硬件,或根据观看距离和个人偏好进行调整。这些调整应使用平台的本地显示设置进行,以便所有应用程序都将使用相同的DPI或缩放因子值。Qt不提供最终用户的设施来配置Qt的高DPI支持的行为。
操作系统可以将缩放因子表示为因子(1.5)、百分比(150%)或每英寸点数(144 DPI)。Qt将这些转换为应用程序看到的设备像素比。在后一种情况下,Qt假设一个“基础”DPI,例如X11上的96,并相应地计算结果设备像素比。
整数缩放因子(例如1.0或2.0)是首选,可得到最佳结果。"四舍五入"缩放因子到25%的增量也可以得到良好的结果。将缩放因子或DPI设置为精确的物理显示DPI可能不会得到良好的视觉效果,因为涉及分数缩放。如果在此情况下应用程序遭受视觉失真,则可以使用QGuiApplication::setHighDpiScaleFactorRoundingPolicy()来限制它将看到的缩放因子。
平台详情
以下表格描述了如何在不同平台上配置高DPI。
平台 | 配置 |
---|---|
macOS | 在显示首选项中为每个显示器设置缩放。macOS会将此设置反馈给Qt作为一个整数设备像素比。 |
Windows | 在显示设置中为每个显示器设置缩放因子。基本缩放因子为100%,可以以25%的增量进行调整。 |
Ubuntu | 在显示设置中设置缩放因子。在Ubuntu 20.04及以后版本中,这可以按每个显示器设置,增量为25%。较早的版本支持将全局缩放设置为100%或200%。 |
X11 | 设置Xft.dpi,或者选择使用物理DPI。见下文“配置X11”。 |
Wayland | Qt读取wl_output::scale ,这仅限于整数值。Wayland合成器通常具有设置缩放因子的配置选项,例如weston --scale 。 |
EGLFS | 将QT_FONT_DPI 设置为所需的逻辑DPI值,例如QT_FONT_DPI=192 。Qt假定基础DPI为96,并相应地缩放UI。 |
注意:某些窗口系统可能有限制,这些限制会反映在Qt中。Qt不为这些限制提供解决方法。相反,考虑在窗口系统级别解决这些问题。
配置X11
向Qt提供的必需配置输入为每屏幕逻辑DPI。目前,X11提供全局逻辑DPI或每屏幕物理DPI。这两者都不是Qt所需要的,这可能会使X11上的DPI配置比其他平台更复杂。
桌面环境(如Ubuntu和Kubntu)实施逻辑DPI缺乏的解决方案,并提供易于配置的高DPI支持。如果您想手动配置X11 DPI设置,则本节描述了Qt读取的X11设置。
某些X11配置工作流程涉及覆盖屏幕报告的物理尺寸,以便使DPI计算产生特定的DPI值。Qt支持此工作流程,但需要选择,如下所述。
确切的配置优先级如下,其中Qt使用第一个可用的选项。请注意,行为取决于使用的Qt版本。Qt 5的行为假定AA_EnableHighDpiScaling已经设置(在Qt 6中不需要此标志)。
X11 DPI配置优先级 | ||
---|---|---|
属性 | 说明 | |
1. Xft/DPI | 来自X设置。全局逻辑DPI值。 | |
2. Xft.dpi | 来自X资源。全局逻辑DPI值。 | |
3. RandR物理DPI [仅Qt 5] | 从randr 报告的每屏幕物理尺寸和像素大小计算的DPI。具体来说,使用xcb_randr_screen_change_notify_event_t 结构的mwidth 和mheight 字段。DPI将被四舍五入到整数并钳位以确保不少于96。 | |
4. 96 DPI | 默认值。 |
QT_USE_PHYSICAL_DPI覆盖
将QT_USE_PHYSICAL_DPI设置为1,以便Qt无条件地使用RandR物理DPI;具体来说,使用的是xcb_randr_screen_change_notify_event_t结构中的mwidth和mheight字段。DPI值将被四舍五入到整数。
配置Windows
Qt将自动使用Windows显示缩放设置;无需特定设置。例如,如果显示器已配置为175%缩放,则Qt应用程序将看到该屏幕上的设备像素比为1.75。
Windows定义了多个DPI Awareness级别,应用程序可以设置以参与高DPI功能。Qt 6默认为Per-Monitor DPI Aware V2。如果您正在组合假设单个全局DPI的代码,则可能需要设置不同的感知级别。这可以通过向qt.conf添加条目来完成。
[Platforms] WindowsArguments = dpiawareness=0,1,2
测试
QT_SCALE_FACTOR
将QT_SCALE_FACTOR环境变量设置为提供应用程序的全局缩放因子。
QT_SCALE_FACTOR=2 ./myapp
这会将所有应用程序几何形状(包括设备像素比)按给定因子缩放,从而独立于可用硬件测试高DPI支持。设置的缩放因子将被Qt原样使用,并且不受舍入策略的影响。
由QWindow::devicePixelRatio()返回的有效设备像素比将是设置的缩放因子和本机设备像素比的乘积。例如,将QT_SCALE_FACTOR设置为2的2x Wayland显示器将导致应用程序看到设备像素比为4。
DprGadget
DprGadget测试应用程序可以用于检查原生配置,以及Qt如何对此作出反应
DprGadget显示窗口的设备像素比,由QWindow::devicePixelRatio()报告。此外还显示窗口所在的屏幕的原生DPI和设备像素比,由QPlatformScreen::logicalDpi()和QPlatformScreen::devicePixelRatio()报告。
显示的值应自动在屏幕上更新并在DPI更改时更新,并且对话框应保持相同的大小。如果不是这样,它可能是一个Qt错误。
DprGadget是Qt的手动测试套件的一部分,可以在qtbase/tests/manual/highdpi/dprgadget
中找到。
环境变量参考
本节列出了Qt认可的高DPI相关环境变量。按字母顺序排列
- QT_ENABLE_HIGHDPI_SCALING 设置为0以禁用高DPI缩放;有效还原到Qt 5默认行为。请注意,这不会影响像Wayland或macOS这样的平台 - 它不会禁用任何本机高DPI支持。此变量仅用于测试目的,我们不建议永久设置它。
- QT_FONT_DPI 设置全局DPI。这是一个为向后兼容性提供的旧式环境变量。
- QT_SCALE_FACTOR 设置全局缩放因子。用于调试和测试目的。
- QT_SCALE_FACTOR_ROUNDING_POLICY 设置缩放因子的舍入策略,该策略应用于从屏幕DPI计算出的缩放因子。支持的值包括
- Round(Qt 5默认值)
- PassThrough(Qt 6默认值)
- QT_SCREEN_SCALE_FACTORS 设置一个屏幕缩放因子列表。列表可以采用两种格式之一;要么是屏幕缩放因子的分号分隔列表(“1;1.5;2”),要么是分号分隔的screen=factor条目(“screenA=1;screenB=1.5;screenC=2”)。不建议设置此环境变量,因为它阻止Qt使用系统DPI值。
- QT_USE_PHYSICAL_DPI 使Qt使用物理DPI而不是逻辑DPI。通常使用逻辑DPI是最佳选择;在逻辑DPI不可用且物理DPI已知正确的情况下可以设置此环境变量。
坐标系参考
- 设备无关像素这是Qt的主坐标系。窗口、小部件、Quick项、事件和屏幕几何图形均以设备无关像素表示。通常,设备无关像素在具有不同设备和屏幕密度的设备上具有恒定的视觉大小。虽然这是一个概括,但具体大小取决于设备配置。
- 设备像素此坐标系用于光栅化和低级图形任务,例如使用OpenGL API时。设备像素坐标系通常与显示的物理坐标系等效,但此等效性不是保证的。例如,macOS和Ubuntu可能会根据显示设置应用额外的缩放。
- 本地像素这是本地API(如Win32或Cocoa)使用的坐标系。根据平台和屏幕配置,本地像素可能与设备无关像素或设备像素等效。
© 2024 The Qt Company Ltd. 本文档中的贡献版权属于各自所有者。提供的文档受自由软件基金会发布的GNU自由文档许可证版本1.3条款许可。Qt及其相关标志是芬兰以及全球其他地区的The Qt Company Ltd.的商标。所有其他商标均为其各自所有者的财产。