Qt实现窗口内的控件自适应窗口大小

**前言:**因为有时候窗口内的控件比较大,但是为了同时操作多个窗口,希望可以根据情况,在调整窗口大小时,控件能自适应大小,于是通过遍历整个界面内的控件,并在调整大小的事件中按比率调整控件大小实现了此功能。有点小问题是文字的大小比较不好控制,还有待优化。

一、变量和函数定义

在窗口类头文件中定义

cpp 复制代码
// 控件根据窗口大小自动调整控件大小 @{
protected:
    /** 窗口尺寸改变时自动调用 **/
    void resizeEvent(QResizeEvent* event) override;
private:
    // 窗口内所有的控件
    QMap<QWidget*, QRect> allWidgetMap;
    // 窗口内所有的布局
    QMap<QLayout*, QRect> allLayoutMap;
    // 窗口原始尺寸
    QSize windowOriginalSize;
    /** 查找窗口内所有的布局和控件 **/
    void findAllLayoutAndWidget(QObject *object);
// 控件根据窗口大小自动调整控件大小 @}

二、查找所有窗口内控件,并在"窗口调整大小" 事件中,实时根据窗口比率调整控件大小

1)函数实现

cpp 复制代码
// 控件根据窗口大小自动调整控件大小 @{
void MyWindow::resizeEvent(QResizeEvent* event)
{
    double scaleX = event->size().width() * 1.0 / windowOriginalSize.width();
    double scaleY = event->size().height() * 1.0 / windowOriginalSize.height();
    for (auto iter = allLayoutMap.begin(); iter != allLayoutMap.end(); ++iter) {
        QLayout* layout = iter.key();
        QRect originalGeometry = iter.value();
        QRect newGeometry(
            originalGeometry.x() * scaleX,
            originalGeometry.y() * scaleY,
            originalGeometry.width() * scaleX,
            originalGeometry.height() * scaleY
            );
        layout->setGeometry(newGeometry);
    }

    for (auto iter = allWidgetMap.begin(); iter != allWidgetMap.end(); ++iter) {
        QWidget* widget = iter.key();
        QRect originalGeometry = iter.value();
        QRect newGeometry(
            originalGeometry.x() * scaleX,
            originalGeometry.y() * scaleY,
            originalGeometry.width() * scaleX,
            originalGeometry.height() * scaleY
            );
        widget->setGeometry(newGeometry);

        QPushButton* btn = dynamic_cast<QPushButton*>(widget);
        // 调整按钮字体大小
        if (btn != NULL) {
            QFont font = btn->font();
            // 根据按钮的宽度/高度调整字体大小,可以根据默认控件的高度和字体的大小比率进行适当调整
            font.setPointSize(btn->height() / 3);
            btn->setFont(font);
        }
        // QLabel* label = dynamic_cast<QLabel*>(widget);
        // 调整标签字体大小
        // if (label != NULL) {
        //     QFont font = label->font();
        //     // 根据按钮的宽度/高度调整字体大小,可以根据默认控件的高度和字体的大小比率进行适当调整
        //     font.setPointSize(label->height() / 2);
        //     label->setFont(font);
        // }
    }
}

void MyWindow::findAllLayoutAndWidget(QObject *object) {
    QLayout *layout = qobject_cast<QLayout*>(object);
    QWidget *widget = qobject_cast<QWidget*>(object);
    if (layout) {
        if (layout->objectName() != "" && !allLayoutMap.contains(layout)) {
            allLayoutMap.insert(layout, layout->geometry());
        }
        for (int i = 0; i < layout->count(); ++i) {
            findAllLayoutAndWidget(layout->itemAt(i)->widget());
        }
    } else if (widget) {
        if (widget != this && widget->objectName() != "" && !allWidgetMap.contains(widget)) {
            allWidgetMap.insert(widget, widget->geometry());
        }
        for (int i = 0; i < widget->children().size(); ++i) {
            findAllLayoutAndWidget(widget->children().at(i));
        }
    }
}
// 控件根据窗口大小自动调整控件大小 @}

2)在构造函数中调用查找控件函数

cpp 复制代码
MyWindow::MyWindow(QWidget *parent) : QWidget(parent), ui(new Ui::MyWindow)
{
    ui->setupUi(this);
    // 控件根据窗口大小自动调整控件大小 @{
    // 延时为了获取的控件初始大小是正确的
    QTimer* t = new QTimer(this);
    connect(t, &QTimer::timeout, this, [=]() {
        t->stop();
        t->deleteLater();
        findAllLayoutAndWidget(this);
        windowOriginalSize = this->size();
    });
    t->start(500);
    // 控件根据窗口大小自动调整控件大小 @}
}
相关推荐
saltymilk9 小时前
使用 C++ 模拟 ShaderLanguage 的 swizzle
c++·模板元编程
xlp666hub15 小时前
Leetcode第五题:用C++解决盛最多水的容器问题
linux·c++·leetcode
得物技术17 小时前
搜索 C++ 引擎回归能力建设:从自测到工程化准出|得物技术
c++·后端·测试
xlp666hub2 天前
Leetcode 第三题:用C++解决最长连续序列
c++·leetcode
会员源码网2 天前
构造函数抛出异常:C++对象部分初始化的陷阱与应对策略
c++
xlp666hub2 天前
Leetcode第二题:用 C++ 解决字母异位词分组
c++·leetcode
不想写代码的星星2 天前
static 关键字:从 C 到 C++,一篇文章彻底搞懂它的“七十二变”
c++
xlp666hub2 天前
Leetcode第一题:用C++解决两数之和问题
c++·leetcode
不想写代码的星星3 天前
C++继承、组合、聚合:选错了是屎山,选对了是神器
c++
不想写代码的星星4 天前
std::function 详解:用法、原理与现代 C++ 最佳实践
c++