高DPI¶
描述Qt对高DPI显示器的支持。
高DPI显示器——也称为视网膜显示器——是相对于其物理尺寸(毫米)具有高分辨率(像素)的显示器,从而产生高像素密度,或高数量的每英寸点数(DPI)。增加的分辨率用于在屏幕上提供更详细的内容(更平滑的文本,更详细的图标),而不是更多的内容(更多的窗口,更大的窗口尺寸)。
Qt 在所有平台上都支持高DPI显示,并提供了一个统一的API,以抽象化任何平台差异。在使用更高级别的API(如Qt Widgets和Qt Quick)时,Qt会自动考虑显示分辨率,应用程序只需提供高分辨率资源,如图像和图标。平台用户偏好的更改会自动被捕捉。
较低级别的图形绘制(例如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类之间的差异,例如触摸目标与鼠标目标的大小。
绘图¶
在使用诸如QPainter等绘图API时,或在Qt Quick中渲染图形基元或文本时,Qt将自动利用高DPI显示器的增加密度。
因此,应用程序可以在一个统一的坐标系中运行,而无需考虑应用程序可能运行的显示密度。
然而,当使用较低级别的绘图API时,例如OpenGL,应用程序需要考虑显示器的设备像素比。这可以通过每个窗口的QWindow::devicePixelRatio()(跟踪窗口在显示器之间移动时的设备像素比)或每个显示器的QScreen::devicePixelRatio()来获取。
像QImage和QPixmap这样的图像缓冲区表示原始像素,因此不在之前描述的与设备无关的坐标系中操作。一个大小为400x400的QImage,设备像素比为2.0,将适合高密度(2x)显示器上的200x200 QWindow,或者如果目标是正常密度(1x)显示器,在绘制过程中将自动缩小到200x200。有关更多详细信息,请参见绘制高分辨率的像素图和图像。
图像资源¶
为了利用高DPI显示器增加的像素密度,应用程序还应包括静态图像资源的高DPI版本。这是通过为高密度资源使用特殊的命名约定来实现的,例如logo@2x.png,并将普通密度图像和高密度图像加载到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和Kubuntu为缺乏逻辑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]|从每个屏幕的物理大小和像素大小计算的 DPI,由 ``randr`` 报告。具体来说,使用 ``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 感知级别,应用程序通过设置这些级别来选择使用高 DPI 功能。默认情况下,Qt 6 是每显示器 DPI 感知 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()返回,将是设置的缩放因子和本机设备像素比的乘积。例如,在2x Wayland显示器上设置QT_SCALE_FACTOR=2将导致应用程序看到的设备像素比为4。
DprGadget¶
DprGadget测试应用程序可用于检查本机配置,以及Qt对其的反应:
DprGadget 显示窗口的设备像素比,这是由 QWindow::devicePixelRatio() 报告的。此外,它还显示窗口所在屏幕的本地 DPI 和设备像素比,这是由 QPlatformScreen::logicalDpi() 和 QPlatformScreen::devicePixelRatio() 报告的。
显示的值应在屏幕和DPI更改时自动更新,对话框应保持相同的大小。如果不是这样,可能是Qt的一个bug。
DprGradget 是 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”),要么是分号分隔的屏幕=因子条目列表(“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(macOS))使用的坐标系。根据平台和屏幕配置,原生像素可能等同于设备独立像素或设备像素。