0


QT解决因屏幕分辨率和缩放产生的界面异常

显示器分辨率和缩放比例

在某些情况下,由于屏幕分辨率和缩放比例不是100%,导致一些界面或字体的显示出现异常。此时需要获取到分辨率和缩放比例等相关参数,加以矫正,使界面在不同分辨率和缩放比例下都显示正常。
以Windows11为例,右键开始图标选择【系统】-【屏幕】,进入如下界面。
在这里插入图片描述
找到【缩放和布局】
在这里插入图片描述
此电脑的最佳缩放和显示器分辨率分别为200%,2560*1440;在此设置下可以达到最佳显示效果,但问题随之而来。

界面异常

正常情况,即100%缩放比例的情况下,一个图像显示窗口及字体如下,
在这里插入图片描述
现在将显示器分辨率和缩放比例调整到2560*1440和200%,同一个界面和字体如下,
在这里插入图片描述
可以看到,图像显示窗口和字体都随之改变,字体变小,图像显示区则直接缩小了1倍,这些结果都能和显示器缩放比例对应上,我们现在知道,显示器缩放比例调整为原来的2倍,则界面显示区随之变为原来的0.5倍。
接下来就是如何通过QT获取到相关参数进而对相应窗口进行尺寸调整。

QT(6.2版本)获取主屏幕分辨率和缩放比例

细心的人可能注意到,第一张图上显示的是两个显示器,其中1为主显示器。直接上QT帮助文档。在帮助文档里找到QScreen Class。
在这里插入图片描述
找到其中几个接口:

 qreal devicePixelRatio()const
 qreal logicalDotsPerInch()const
 qreal logicalDotsPerInchX()const
 qreal logicalDotsPerInchY()const

其解释说说明如下,简单解释下:
在这里插入图片描述
此属性保存物理像素和设备无关像素之间的屏幕比率。主要看这句就行,

Common values are 1.0 on normal displays and 2.0 on "retina" displays. Higher values are also possible

正常情况下值为1,解释下"retina" displays。

视网膜成像显示技术,一种超高分辨率显示技术。有兴趣可以百度一下
Retina Display

用法我们后面说。

在这里插入图片描述
逻辑分辨率,和物理分辨率区分,物理分辨率我们用不到。所谓逻辑分辨率就是显示器每一英寸上的逻辑点数,就是我们常说的DPI。通常情况下XY方向值一样,平均值自然也一样。可根据实际情况选择使用。

该类通过静态接口函数获取

QScreen *screen = qApp->primaryScreen();

代码测试

下面进行无聊的测试环节。

    QScreen *screen = qApp->primaryScreen();
    qreal dpiVal = screen->logicalDotsPerInch();
    qreal ratioVal = screen->devicePixelRatio();qDebug()<< dpiVal << ratioVal;

改个缩放值,运行一遍代码。
在这里插入图片描述
输出值如下
window 缩放参数100%125%150%175%200%225%logicalDotsPerInch96120728496108devicePixelRatio112222
规律很明显,稍微有点数学常识的人应该都可以总结出来,他们之间存在着线性关系,即

window缩放参数 / 100% = logicalDotsPerInch * devicePixelRatio / 96

实际应用

找到规律,就好办了,在使用的地方定义一个函数。

doubleSomeClass::GetScreenFactor(){//获取屏幕缩放倍数
    QScreen *screen = qApp->primaryScreen();constint baseValue =96;//100%时为96
    qreal dpiVal = screen->logicalDotsPerInch();
    qreal ratioVal = screen->devicePixelRatio();qDebug()<< dpiVal << ratioVal;return dpiVal * ratioVal / baseValue;}

具体哪里会用到就要根据自己的实际情况了,最常见的两个地方是

  • 界面构造或者初始化时
  • 界面尺寸改变时

以一段项目代码为例

//界面构造或者初始化时...auto factor = d->GetScreenFactor();
    d->pHalconView = std::make_unique<HalconView>();double iWindowWidth = ui->widget_view->width()* factor;double iWindowHeight = ui->widget_view->height()* factor;
    QPoint qPos = ui->widget_view->mapFromParent(QPoint(0,0));
    d->pHalconView->InitWindow(qPos.x(), qPos.y(), iWindowWidth, iWindowHeight,(void*)(ui->widget_view->winId()), strWindowName);...
//重写resizeEventvoidSomeClass::resizeEvent(QResizeEvent *event){...auto factor = d->GetScreenFactor();
        d->pHalconView->ChangeWindowSize(0,0, ui->widget_view->width()* factor, ui->widget_view->height()* factor);...QWidget::resizeEvent(event);}

就是在原有数据的基础上乘以这个缩放因子。
结果就不一一展示了,在不同缩放比例下已经一样了。
在这里插入图片描述

需要说明下:这个常量DPI96在常见的显示器都是这个值,没有测试过所有显示器

多显示器

前面的方法是获取主显示器的参数值,多显示器情况下,也提供了接口

QList<QScreen *>QGuiApplication::screens()

这里就不赘述了

拓展

相信很多人都见过,一些应用程序在屏幕分辨率或缩放参数改变后或弹窗提示,以企业微信为例
在这里插入图片描述
这个也很简单,QScreen类有很多信号
在这里插入图片描述
只要绑定个槽函数,就能随时获取屏幕的参数变化,执行后续的操作,在线修改或者像企业微信那样做个提醒什么的,用法就很随意了。

    QScreen *screen = qApp->primaryScreen();connect(screen,&QScreen::logicalDotsPerInchChanged,[](double v){qDebug()<<"new dpi "<< v;});
标签: qt ui

本文转载自: https://blog.csdn.net/qq_27450255/article/details/127262021
版权归原作者 家有一枚袁宝 所有, 如有侵权,请联系我们删除。

“QT解决因屏幕分辨率和缩放产生的界面异常”的评论:

还没有评论