简 述: 高分屏、DPIPPI、屏幕分辨率的一些基本知识,以及使用 Qt 处理高分屏的一些方法集合归纳。

[TOC]


本文初发于 “偕臧的小站“,同步转载于此。


基础

英寸: inch,复数:inches;缩写为in或″,或 英吋,简作 。1 英寸(inch) = 2.54 厘米(cm)= 25.4 毫米(mm)。

像素: pixel 或 pel,为影像显示的基本单位,可看作一个点或方块(不是距离单位)。每个像素有自己的RGB值,单位面积的像素越多,则表示其分辨率越高。

PPI: 每英寸的像素个数(此处一英寸为对角线长度、且说的是像素密度)。由 分辨率 中X或Y轴的数字除以该轴的长度(英寸),可得该轴的像素每英寸密度。

DPI: 每英寸的点个数(此处一英寸为对角线长度、且说的是打印点密度)。


PPI 通常使用于计算机屏幕,DPI 通常使用于打印机;但是这两者之间通常被混用,需要在具体的上下文去理解其含义。



屏幕尺寸: 指的是一个电子设备的屏幕对角线的长度。

分辨率: 是指宽度上和高度上最多能显示的物理像素点个数(说的是块屏幕的像素尺寸)。

点距: 像素与像素之间的距离,点距和屏幕尺寸决定了分辨率大小

设备像素(又称为物理像素): 指设备能控制显示的最小物理单位,意指显示器上一个个的点。从屏幕在工厂生产出的那天起,它上面设备像素点就固定不变了,和屏幕尺寸大小有关,单位 pt。

设备独立像素(也叫密度无关像素或逻辑像素): 可以认为是计算机坐标系统中得一个点,这个点代表一个可以由程序使用的虚拟像素(比如: css像素),这个点是没有固定大小的,越小越清晰,然后由相关系统转换为物理像素。

css像素(也叫虚拟像素): 指的是 CSS 样式代码中使用的逻辑像素,在 CSS 规范中,长度单位可以分为两类,绝对(absolute)单位以及相对(relative)单位。px 是一个相对单位,相对的是设备像素(device pixel)。

设备像素比(devicePixelRatio): 设备像素比 = 设备像素 / 设备独立像素。(在Retina屏的iphone上,DPR为2,1个css像素相当于2个物理像素)

  • 普通密度桌面显示屏的 devicePixelRatio=1
  • 高密度桌面显示屏(Mac Retina)的 devicePixelRatio=2
  • 主流手机显示屏的 devicePixelRatio=2或3


视网膜显示屏 == Retina显示屏

高PPI(硬件) + HiDPI渲染(软件) = 更细腻的显示效果(retina)


方案

提供几种解决方案,若有更好的欢迎补充

// 2022-06-18 高分屏适配的许多尝试:
//【方案一】 Qt 5.14+, 解决 1.5会缩放到2倍,不过显示会有问题,比如按钮之间时不时会有虚线。
qputenv("QT_ENABLE_HIGHDPI_SCALING", "1");
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy);

//【方案二】 Qt5.12 替代方案
qputenv("QT_AUTO_SCREEN_SCALE_FACTOR", "1.5");

// 【方案三】 Qt5.12 替代方案
#if (QT_VERSION >= QT_VERSION_CHECK(5,9,0))
    qputenv("QT_SCALE_FACTOR", "1.0"); // 全局缩放因子 https://blog.csdn.net/u014410266/article/details/107488789
    QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif

//【方案四】 使用 windows 自带的
exe 统计目录下使用 qt.conf 文件

// 三种方案 https://blog.csdn.net/hanjiang08/article/details/124653265
// https://blog.csdn.net/qq_18260845/article/details/103861201
// https://blog.csdn.net/feiyangqingyun/article/details/124860909
    
#if(QT_VERSION > QT_VERSION_CHECK(5,6,0))
//    QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);  // 2K、4K 2@ 倍;获取的分辨率 4K 下实际为 /2 后。 此行需在 QApplication a(argc,argv);前面
//    QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);    // 控制图片缩放质量,svg 的图片不会模糊在 4K 上。   此行无需在 QApplication a(argc,argv);前面
    qApp->setAttribute(Qt::AA_UseHighDpiPixmaps);  // 若上面一行没有生效,但是此行可以生效
#endif
```

物理 DPI 和 逻辑 DPI

A note on logical vs physical dots per inch: physical DPI is based on the actual physical pixel sizes when available, and is useful for print preview and other cases where it’s desirable to know the exact physical dimensions of screen displayed contents.

Logical dots per inch are used to convert font and user interface elements from point sizes to pixel sizes, and might be different from the physical dots per inch. The logical dots per inch are sometimes user-settable in the desktop environment’s settings panel, to let the user globally control UI and font sizes in different applications.

source:https://doc.qt.io/qt-5/qscreen.html

物理 DPI:基于实际的物理像素尺寸

逻辑 DPI:将字体和用户界面元素从点大小转换为像素大小。可在系统中由用户手动更改(如开启 150% 缩放)。

由测试可知,在”设置-显示”中,调节”显示器分辨率”,会改变获取的 Physical DPI 数值;而调节”缩放比”,会改变 Logical DPI 数值。

------------------------------------------
4K(3480*2160) 150% 缩放比
------------------------------------------
devicePixelRatio: 1 physicalSize: QSizeF(600, 340)   refreshRate: 59  size: QSize(3840, 2160) Scale: 1.5
Physical DPI: 161.962   DPIX: 162.56   DPIY: 161.365
 Logical DPI: 144   DPIX: 144   DPIY: 144

------------------------------------------
4K(1920*1080) 150% 缩放比
------------------------------------------
devicePixelRatio: 1 physicalSize: QSizeF(600, 340)   refreshRate: 59 size: QSize(1920, 1080)  Scale: 1.5
Physical DPI: 80.9812   DPIX: 81.28   DPIY: 80.6824
 Logical DPI: 144   DPIX: 144   DPIY: 144
 
------------------------------------------
4K(1920*1080) 100% 缩放比
------------------------------------------
devicePixelRatio: 1 physicalSize: QSizeF(600, 340)   refreshRate: 59 size: QSize(1920, 1080)  Scale: 1  
Physical DPI: 80.9812   DPIX: 81.28   DPIY: 80.6824
 Logical DPI: 96   DPIX: 96   DPIY: 96

Ref