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);
    // 控件根据窗口大小自动调整控件大小 @}
}
相关推荐
重生之我在VS写bug1 小时前
【C++知识总结2】C++里面的小配角cout和cin
数据结构·c++·算法
pzn25062 小时前
蓝桥杯练习题
c++·算法·蓝桥杯
斯凯利.瑞恩2 小时前
RabbitMQ代码实战2
qt·rabbitmq·ruby
捕鲸叉2 小时前
C++设计模式之组合模式中适用缓存机制提高遍历与查找速度
c++·设计模式·组合模式
奶茶戒断高手3 小时前
【CSP CCF记录】201903-2第16次认证 二十四点
数据结构·c++·算法
白嫩豆腐3 小时前
iced源码分析
ui·rust
_大菜鸟_3 小时前
修改element-ui-时间框date 将文字月份改为数字
javascript·vue.js·ui
scoone5 小时前
C++中的原子操作:原子性、内存顺序、性能优化与原子变量赋值
开发语言·c++
轩情吖5 小时前
模拟实现Bash
linux·c语言·开发语言·c++·后端·bash·环境变量