1.大致思路
在自己的电脑打包的软件在不同分辨率下会有问题无法正常使用,使用Qt自己的高分辨率缩放整体是可以实现的,但是会有一些地方很奇怪不太好用,所以自己实现一下。思路就是通过获取屏幕的分辨率自己计算出一个缩放因子,然后手动适配一下,将每个控件的大小坐标都乘上这个缩放因子就可以实现了。
2.实现功能
字体的大小会随着系统的缩放变大变小,所以也需要计算一下字体的缩放因子来调节
#ifdef Q_OS_WIN
#include <windows.h>
#include <WinUser.h>
#include <wingdi.h>
#include <dbghelp.h>
#endif
qreal adjScale;//针对ui缩放因子
qreal adjFontScale;//针对字体的缩放因子
在main函数中加入,这里以1920*1080为例
HDC desktopDc = GetDC(NULL);
float xPix = GetDeviceCaps(desktopDc, DESKTOPHORZRES);
float yPix = GetDeviceCaps(desktopDc, DESKTOPVERTRES);
float xDotsInch = GetDeviceCaps(desktopDc, LOGPIXELSX);
adjScale = 1.0;
qreal cx = GetSystemMetrics(SM_CXSCREEN);
qreal cy = GetSystemMetrics(SM_CYSCREEN);
// 计算windows的scale(100%,125%,200%,...)
float winScale = xPix / cx;
// 如果是宽屏,则修改cx为16/9比例的大小
if (cx*9 > cy*16) {
cx = cy * 16 / 9;
xPix = yPix * 16 / 9;
}
// 计算缩放比例
adjScale = xPix / 1920;
adjFontScale = adjScale / winScale;
然后在ui里面调用一下这个方法,如果有很多子页面,可以先全部创建完再调用,就可以不用重复写很多次了
QList<QObject*> objectList = findChildren<QObject*>();
for(auto object:objectList)
{
if(QWidget *widget = qobject_cast<QWidget*>(object))
{
int x = widget->x();
int y = widget->y();
int width = widget->width();
int height = widget->height();
widget->setGeometry(x*adjScale,y*adjScale,width*adjScale,height*adjScale);
//如果有用到QSpinBox类型,需要加上,否则字体大小会无法改变
if(widget->objectName()=="qt_spinbox_lineedit") continue;
QFont font = widget->font();
int pointSize = font.pointSize();
int pixSize = font.pixelSize();
if (pixSize > 0) {
font.setPixelSize(ceil(pixSize*adjScale));
}
if (pointSize > 0) {
font.setPointSize(ceil(pointSize*adjFontScale));
}
widget->setFont(font);
}
}
3.注意的点
- 如果有用到QSpinBox类型,不能对qt_spinbox_lineedit设置字体大小,否则字体大小会无法改变
- 字体大小如果设置的是pointSize 需要乘上adjFontScale的因子,如果是pixSize,则需要乘上adjScale因子
- 如果控件设置了固定大小,setGeometry将不起效果,必须额外设置一下
- 如果设置了最大值或者最小值,也必须额外设置一下
ui->signal_bt->setFixedSize(15*adjScale,15*adjScale);
ui->Line->setMinimumWidth(ui->Line->minimumWidth()*adjScale);