背景
- 在不同的分辨率和缩放份额下,对客户端的UI进行适配
- 使用qt版本5.15.3
- 使用qt画板.ui进行界面布局
适配计划
计划1
交由Windows进行处理
创建 qt.conf 文件,并增加到 .qrc 资源文件中
qt.conf 文件内容
[Platforms]
WindowsArguments = dpiawareness=0
计划2
由qt进行接收
需求5.14之后才支持
QCoreApplication::SetAttribute(Qt::AA_EnableHighDpiScaling);
QCoreApplication::SetAttribute(Qt::AA_UseHighDpiPixmaps);
会进行四舍五入,整数倍缩放。即
100% <= scale < 150% 按 100% 缩放
150% <= scale < 250% 按 200% 缩放
以此类推…
未能符合实践想要的根据屏幕设置的实践 scale 等比缩放
原因:存在默认的缩放战略 round 会对份额进行四舍五入
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy:Round);
HighDpiScaleFactorRoundingPolicy 的枚举下有多中战略可以选择,其中 PassThrough 是根据实践屏幕设置的 scale 值进行等比缩放
留意点
- 上述高分屏适配代码需求增加到使用初始化之前
int main(int argc, char *argv[]) {
// 高分屏适配
...
QApplication application();
...
}
开发中遇到的问题和解决办法
修改桌面分辨率之后,不能同步刷新使用
解决计划:在所有屏幕增加DPI变动的信号槽
// 获取所有屏幕
QList<QScreen *> screens = QApplication::screens();
// 遍历屏幕目标增加信号槽
...
connect(screen, &QScreen::logicalDotsPerInchChanged, this, &MainWindow::OnLogicalDotsPerInchChanged);
...
// 槽函数实现
void MainWindow::OnLogicalDotsPerInchChanged(qreal dpi)
{
// 获取当时使用方位
QPoint point = QPoint(this->screen()->geometry().x(), this->screen()->geometry().x());
// 遍历screen,获取使用所在方位screen进行使用刷新
for (auto &screen : QApplication::screens()) {
if (QApplication::screenAt(point)->name() == screen->name()) {
update();
}
}
}
多个不同dpi的屏幕之间来回拖动,超越鸿沟时,可能会呈现异常放大
系统进行了DWM虚拟化处理,可能呈现计算错误的状况
解决计划:在 QApplication 初始化之前调用 windows 函数
SetProcessDPIAware();
参考Windows文档
setProcessDPIAware 函数 (winuser.h) – Win32 apps | Microsoft Learn
遗留问题
屏幕缩放份额在放大时,怎么实现使用缩放份额最大值的约束?
例如电脑屏幕缩放份额300%时,约束使用份额为250%