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);
    // 控件根据窗口大小自动调整控件大小 @}
}
相关推荐
charlie11451419134 分钟前
深探std::vector:三指针、扩容与迭代器失效
开发语言·c++·开源项目
laplaya44 分钟前
ROS常用消息之PointCloud2
c++
沙盘客1 小时前
典型应用与趋势:作战实验、AI 决策与数字孪生
c++·人工智能·经验分享
Quz2 小时前
QML MouseArea:点击、悬停与坐标获取
qt
ShineWinsu2 小时前
对于 C++ :从 const、constexpr、auto、decltype 到 type_traits、SFINAE 与 Concepts的解析
c++
程与留2 小时前
04_Qt项目构建流程深度解析——MOC、UIC、RCC 的作用与原理
qt
Quz2 小时前
QML MouseArea 事件:单击双击、长按与多按键检测
qt
_Narcissus_2 小时前
B树概念及操作笔记(含完整代码实现)
c语言·数据结构·数据库·c++·笔记·b树·算法
筠筠喵呜喵3 小时前
解决问题:QNX平台调用glReadPixels卡滞
c++·unix
秋田君3 小时前
SqlServer2022 服务以及客户端可视化安装详细教程
qt