QT窗口缩放——支持任意分辨率

QT窗口缩放——支持任意分辨率

作者:hws000(hws.000#163.com)
声明:版权所有,转载请联系作者。
出处:https://blog.simbot.net/index.php/2018/10/17/qtscalefont/

通过修改子窗口大小及字号,适应任意分辨率。

1.方法描述

(1)使用setMaximumSize、setMinimumSize函数修改子窗口大小,使其跟随主窗口变化;
(2)宽、高缩放比例不同时,通过qt的自动布局功能,调整子窗口的位置;
(3)通过setPointSizeF函数控制字体变化。
自动布局功能不讲解,只讲(1)(3)。

2.上代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
void MainWindow::resizeEvent(QResizeEvent* event)
{
    QSize size = event->size();
    float scaleX = size.width() / 1920.0f;//原始分辨率
    float scaleY = size.height() / 1080.0f;
    float scale = std::min(scaleX, scaleY);//不是等比缩放时,选择最小的缩放比,可以通过自动布局调整窗口位置
    const QObjectList& list = this->children();//枚举子窗口,并设置大小
    foreach(QObject* obj, list) {
        if (obj->isWidgetType()) {
            QWidget* child = (QWidget*)obj;
            if (std::abs(scale - _lastScale) > 0.03) {//当缩放比例超过阈值时才进行,因为窗口宽高是整数,频繁缩放会使窗口变形
                scaleChildWidget(child, scale / _lastScale);
            }
        }
    }
    
    if (std::abs(scale - _lastScale) > 0.03) {
        _lastScale = scale;
    }
}
void MainWindow::scaleChildWidget(QWidget* widget, float scale)
{
    const QObjectList& list = widget->children();
    foreach(QObject* obj, list) {
        if (obj->isWidgetType()) {
            QWidget* child = (QWidget*)obj;
            if (scale < 1) {
                scaleChildWidget(child, scale);//处理所有子窗口
            }
            QSize max = child->maximumSize();
            QSize min = child->minimumSize();
            if (max.width() < 65536) {//子窗口需要设置初始值
                child->setMaximumSize(max * scale);
            }
            if (min.width() > 0) {
                child->setMinimumSize(min * scale);
            }
            QFont font = child->font();//缩放字体
            font.setPointSizeF(font.pointSizeF() * scale);
            child->setFont(font);
            if (scale > 1) {
                scaleChildWidget(child, scale);
            }
        }
    }
}