QT 使用全局缩放进行全分辨率适配(QT_SCALE_FACTOR)

事出有因

因为现在做的一个项目是全程全屏显示的。因此不同屏幕分辨率对程序界面的影响太大。而UI设计的时候又没有过多的考虑自动布局这方面的事。
虽然在刚开始做界面的时候已经尽量利用自动布局来做,但是有些控件提供的图片大小不太合适,在做的时候只能给控件设置固定大小。在测试不同分辨率的时候发现界面展现的效果不同。于是就开始想办法做分辨率适配。

偶然事件

具体忘记当时在搜索什么东西了,大概应该是高分屏适配的问题。在qt的一篇官方文档中发现了这个好东西:

QT_SCALE_FACTOR [numeric] defines a global scale factor for the whole application, including point-sized fonts.

QT_SCALE_FACTOR

它是一个QT的环境变量,看它的字面意思是缩放因子或者叫缩放系数
这东西咋用的呢?看一段示例代码:

qputenv("QT_SCALE_FACTOR", "2.0");

就这么简单。但是有个条件,就是这句代码需要放再QApplication实例初始化之前。
它有什么效果呢?
它是用来控制整个程序界面的所有元素的缩放比例的一个环境变量。上面这句代码的效果就是将整个界面放大为原来的2倍。
来看效果:
无缩放
两倍缩放

怎么用呢

从上面两张图可以看出来,在缩放的时候是整个界面进行缩放的。不管是pt单位还是px单位都进行了缩放 。
那么代码就可以这样写。

	//这个是Windows平台用来获取屏幕宽度的代码,
	//因为在qApplication实例初始化之前,QGuiApplication::screens();无法使用。
	qreal  cx = GetSystemMetrics(SM_CXSCREEN);
	qreal scale = cx / 960;				// 960 = 1920 / 2
	qputenv("QT_SCALE_FACTOR", QString::number(scale).toLatin1());

上面代码大概意思就是通过对比当前屏幕的分辨率和设计分辨率(960×540)来确定程序的整体缩放比例。
这样无论在哪种分辨率情况下界面展现的效果都是一样的。
备注:
为什么设计分辨率是960×540。因为它是1920×1080的一半。而现在设备的常用分辨率基本上都是1920×1080;更重要的是我自己的电脑分辨率就是1092×1080,因此我的界面设计的时候就是按照1920×1080分辨率设计的。这样的话我只需要将界面上所有元素的大小减半就行了。另外一个重要的原因就是缩放系数不能小于1.0,不然会出bug,至于到底会发生什么,自己试试就知道了。

后遗症

通过上面两张图,你会发现这个全局缩放引发了两个问题:

  1. 图片放大的时候有锯齿。
  2. 字体在缩放的时候质量不太好。

因此需要另外两个东西来解决这两个问题。

  1. 调整图片缩放质量
    	//控制图片缩放质量
    QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
    
  2. 文字质量
    这需要使用另外一个东西”qt.conf“。
    内容如下。
    [Platforms]
    WindowsArguments = fontengine=freetype
    
    将这个文件放入程序的资源中。路径为":/qt/etc/qt.conf"

来看效果:
调整质量

注意事项

缩放系数必须大于等于1.0,不然会出现一些奇怪的问题。而且必须是小数形式的字符串。即使缩放系数经过计算后是整数也要写成小数形式。即1920/960 = 2要写成2.0传递进去。
至于获取屏幕尺寸的问题,有些代码提供了一个思路,就是先初始化一个临时的QApplocation获取到屏幕大小后再释放掉,我不建议这么做,因为在我的项目中这样做引起了一些bug,偶尔会闪退。建议自己根据平台不同多写几行代码。

吐槽

QQ截图另存为jpg的时候画质是真的低。

bug修复

由于Windows本身显示缩放机制的存在,上面用来获取屏幕分辨率的方法获取到的并不是真实数据。改用以下方法获取屏幕分辨率。

	DEVMODE NewDevMode;
	//获取屏幕设置中的分辨率
	EnumDisplaySettings(0, ENUM_CURRENT_SETTINGS, &NewDevMode);
	qreal  cx = NewDevMode.dmPelsWidth;			//当前设置的屏幕宽度
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值