马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
配景
工作中须要面临触控大屏的4K分辨率场景,同时也有越来越多人开始利用高分屏,原来多基于1080p分辨率开辟的Qt步调无法很好适配更高的分辨率。
没有特意针对高分辨率场景做适配时,Qt应用的表现通常有两种环境:
- 分辨率高的环境下,应用界面表现特别小
- 应用界面表现的巨细跟随缩放比例的设置,但又没有完全跟随
题目分析
想要办理以上题目,起首须要相识Qt的分辨率适配机制,再根据机制分析题目缘故起因。
Qt提供的分辨率适配本领
1、Qt::AA_EnableHighDpiScaling属性
从Qt5.6开始,支持通过QApplication::setAttribute(Qt::AA_EnableHighDpiScaling)启用高DPI缩放。设置之后,Qt会自动根据体系的DPI设置来缩放界面元素,此属性须要在创建QApplication对象之前设置。
留意:Qt5.6中引入了Qt::AA_DisableHighDpiScaling属性关闭全部缩放,优先级高于Qt::AA_EnableHighDpiScaling。
2、环境变量缩放
同样是从Qt 5.6开始支持,此处引用Qt官方文档内容:
- QT_AUTO_SCREEN_SCALE_FACTOR[boolean] :启用基于表现器像素密度的自动缩放,这不会更改磅值字体的巨细,多个屏幕大概会得到差别的比例系数
- QT_SCALE_FACTOR[numeric]:界说整个应用步调的全局缩放因子,包罗磅巨细的字体
- QT_SCREEN_SCALE_FACTORS
3、缩放计谋设置
从Qt5.14开始,支持利用以下接口举行缩放计谋设置 :- QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
复制代码
4、Qt6的缩放计谋
从Qt6.0开始默认开启Qt::AA_EnableHighDpiScaling,而且不答应关闭,但可以通过setHighDpiScaleFactorRoundingPolicy函数影响缩放计谋。
题目分析
1、分辨率高的环境下,应用界面表现特别小
由于Qt6.0之后才默认开启Qt::AA_EnableHighDpiScaling自动缩放,在此之前的版本,应用没有实现任何分辨率适配的逻辑,且最开始界面操持是按照1080p的尺寸实现,在高分辨率时自然表现特别小。
2、应用界面表现的巨细跟随缩放比例的设置,但又没有完全跟随
Qt应用启用了Qt::AA_EnableHighDpiScaling的环境下,会自动举行缩放调解,但自动调解的默认计谋是对体系的缩放比例举行四舍五入,以是会有差别。
办理方案
在相识Qt的分辨率适配机制,并分析出缘故起因后,可以根据自己的缩放需求举行分辨率适配。
1、盼望跟随体系缩放比例举行缩放
这种方式比力简朴,可通过以下方式实现:- int main(int argc, char *argv[])
- {
- QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
- QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Round); // 此处根据希望实现的缩放策略进行设置
- QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
-
- QApplication a(argc, argv);
- ExampleWidget w;
- w.show();
- return a.exec();
- }
复制代码 2、无论体系分辨率及缩放比例怎样设置,应用表现巨细和屏幕始终保持相对同等
这种方式无论怎样修改分辨率和缩放比例,应用在屏幕上表现的巨细,始终保持稳固。
须要处理惩罚两个地方,第一是在QApplication之前设置QT_SCALE_FACTOR环境变量:- void useCustomScale()
- {
- // 分辨率适配(Qt6之前可采用这个方式,Qt6之后可能会强制使用默认适配,可能需要找其他方法禁用默认适配规则)
- QApplication::setAttribute(Qt::AA_DisableHighDpiScaling); // 禁用Qt默认适配
- QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
- // 采用自定义的缩放设置:不关心系统缩放设置,根据屏幕分辨率设置缩放比例
- // 同时保持程序宽高相对屏幕大小固定(这一点需要设置程序窗口fixedsize时进行)
- int screenWidth = 0;
- int screenHeight = 0;
- #ifdef __linux__
- Display *display = XOpenDisplay(NULL);
- if (nullptr == display)
- {
- return;
- }
- Screen *screenInfo = ScreenOfDisplay(display, DefaultScreen(display));
- if (nullptr != screenInfo)
- {
- screenWidth = screenInfo->width;
- screenHeight = screenInfo->height;
- }
- XCloseDisplay(display);
- #endif
- #ifdef _WIN32
- HDC hdc_screen = GetDC(0);
- screenWidth = GetDeviceCaps(hdc_screen, DESKTOPHORZRES);
- screenHeight = GetDeviceCaps(hdc_screen, DESKTOPVERTRES);
- ReleaseDC(0, hdc_screen);
- #endif
- // 应用是基于1080p设计开发,因此以1080p为基准
- double scale = (double)screenWidth / 1920;
- if (scale < 1.25) { scale = 1.0; }
- else if (scale >= 1.25 && scale < 1.75) { scale = 1.5; }
- else if (scale >= 1.875) { scale = 2.0; }
- // 由于该变量需要在app之前调用,所以QScreen无法使用,需要用系统的获取屏幕分辨率接口
- QString scaleFactor = QString::number(scale, 'f', 1);
- qputenv("QT_SCALE_FACTOR", QByteArray::fromStdString(scaleFactor.toStdString()));
- }
复制代码 别的,须要设置步调宽高相对屏幕巨细固定:- QRect screenGeometry = QApplication::desktop()->screenGeometry();
- int screen_width = screenGeometry.width();
- int screen_height = screenGeometry.height();
- // 应用是基于1080p设计开发,因此以1080p为基准
- setFixedSize(fixedWidth / 1920 * screen_width, fiexdHeight / 1080 * screen_height);
复制代码 其他留意点
以上的方法可以大概实现应用团体的缩放适配,但是应用内部的笔墨、图像等内容,在缩放时还是有大概会出现题目,以下简朴例举几种环境:
1、设置缩放计谋后,有大概出现图片/图标暗昧的环境。只管利用SVG图,同时可以通过QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps)优化暗昧。
2、通过QPainter的方式实现绘制笔墨时,setPixelSize和setPointSize可顺应于差别的缩放计谋。
|