【Qt】布局之道:Qt界面设计中的五大布局管理器:垂直布局QVBoxLayout,水平布局QHBoxLayout,网格布局QGridLayout,表单布局QFormLayout,QSpacerItem

前言:

在现代软件开发中,用户界面的设计和布局是至关重要的一环。一个直观、美观且响应式的界面不仅能提升用户体验,还能使应用更加易于使用。Qt框架,作为跨平台开发的强大工具,提供了多种布局管理器来帮助开发者轻松实现复杂界面的布局。本文将详细介绍Qt中的五种主要布局管理器:垂直布局、水平布局、网格布局、表单布局以及Spacer的使用,并通过代码示例展示如何使用这些布局管理器来创建灵活且自适应的界面。

之前把控件放到界面上,都是靠“手动”的方式来布局的。这种调整方式是不科学的!

  1. 手动布局的方式非常复杂,而且不精确。
  2. 无法对窗口大小进行自适应。

所以Qt就引入了:布局管理器

  1. 垂直布局
  2. 水平布局
  3. 网格布局
  4. 表单布局

1. 垂直布局

使用 QVBoxLayout 表示垂直的布局管理器. V 是 vertical 的缩写.
在这里插入图片描述
Layout 只是用于界面管理,并没有提供信号。

1.1. 代码示例: 使用 QVBoxLayout 管理多个控件.

#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QVBoxLayout>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 创建三个按钮,使用垂直布局管理器管理起来
    QPushButton* button1 = new QPushButton("按钮1");
    QPushButton* button2 = new QPushButton("按钮2");
    QPushButton* button3 = new QPushButton("按钮3");

    // 创建布局管理器
    QVBoxLayout* layout = new QVBoxLayout();
    layout->addWidget(button1);
    layout->addWidget(button2);
    layout->addWidget(button3);

    // 把布局管路器添加到窗口中
    this->setLayout(layout);
}

Widget::~Widget()
{
    delete ui;
}

在这里插入图片描述
按钮随着窗口的变化而调整。

每个widget中只能设置一个布局管理器,如果我们想使用多个呢?

通过图形化界面拖两个布局框
在这里插入图片描述
如果在代码中创建 layout,其实只创建一个 layout
如果在 QtDesigner 中创建的 layout, 先创建了一个 Widget, 然后再这个新的 Widget 中添加了一个 layout。
在这里插入图片描述
从.ui 文件中可以看出 layout 标签表示的是一个布局管理器的本体,外面自动创建出了一个 Widget。
每个 layout 里面又可以包含若干个item(也就是一个按钮)

刚才是先拖 了layout 过去,然后再往 layout 中拖其他控件。
也可以先拖其他的控件,给这些些控件套上 layout
在这里插入图片描述
把选中的若干控件外头套上一个 垂直分布的 layout。
在这里插入图片描述
各种边距,属性也是可以进行修改的。

2. 水平布局

使用 QHBoxLayout 表示垂直的布局管理器. H 是 horizontal 的缩写。
在这里插入图片描述

2.1. 代码示例: 使用 QHBoxLayout 管理控件

#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QHBoxLayout>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    QPushButton* button1 = new QPushButton("按钮1");
    QPushButton* button2 = new QPushButton("按钮2");
    QPushButton* button3 = new QPushButton("按钮3");

    QHBoxLayout* layout = new QHBoxLayout();
    layout->addWidget(button1);
    layout->addWidget(button2);
    layout->addWidget(button3);

    this->setLayout(layout);
}

Widget::~Widget()
{
    delete ui;
}

在这里插入图片描述

2.2. 代码示例: 嵌套的 layout

布局管理器之间,也是可以嵌套的。

#include "widget.h"
#include "ui_widget.h"
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QPushButton>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 创建一个垂直的布局管理器
    QVBoxLayout* vlayout = new QVBoxLayout();
    this->setLayout(vlayout);

    // 添加两个按钮进去
    QPushButton* button1 = new QPushButton("按钮1");
    QPushButton* button2 = new QPushButton("按钮2");
    vlayout->addWidget(button1);
    vlayout->addWidget(button2);

    // 创建水平布局管理器
    QHBoxLayout* hlayout = new QHBoxLayout();

    // 添加两个按钮进去
    QPushButton* button3 = new QPushButton("按钮3");
    QPushButton* button4 = new QPushButton("按钮4");
    hlayout->addWidget(button3);
    hlayout->addWidget(button4);

    // 把水平布局管理器添加到垂直布局管理器内部
    vlayout->addLayout(hlayout);
}

Widget::~Widget()
{
    delete ui;
}

在这里插入图片描述

3. 网格布局

Qt 中还提供了 QGridLayout 用来实现网格布局的效果. 可以达到 M * N 的这种网格的效果。
核心属性

整体和 QVBoxLayout 以及 QHBoxLayout 相似。但是设置 spacing 的时候是按照垂直水平两个方向来设置的。

在这里插入图片描述

3.1. 代码示例: 使用 QGridLayout 管理元素

#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QGridLayout>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    QPushButton* button1 = new QPushButton("按钮1");
    QPushButton* button2 = new QPushButton("按钮2");
    QPushButton* button3 = new QPushButton("按钮3");
    QPushButton* button4 = new QPushButton("按钮4");

    QGridLayout* layout = new QGridLayout();

//    // 四个按钮 两行分布
//    layout->addWidget(button1, 0, 0);
//    layout->addWidget(button2, 0, 1);
//    layout->addWidget(button3, 1, 0);
//    layout->addWidget(button4, 1, 1);

//    // 单行分布, 这个写法就相当于水平布局了
//    // 此时大家的 行数 只要是一样第即可,不一定非得是 0
//      layout->addWidget(button1, 0, 0);
//      layout->addWidget(button2, 0, 1);
//      layout->addWidget(button3, 0, 2);
//      layout->addWidget(button4, 0, 3);


//    // 单列分布,这个写法就相当于垂直布局了
//    layout->addWidget(button1, 0, 0);
//    layout->addWidget(button2, 1, 0);
//    layout->addWidget(button3, 2, 0);
//    layout->addWidget(button4, 3, 0);

    // 斜着布局,这种写法是每个按钮独占一行和一列
    // 即使写成 100,100,也不会在中间搞出很大的控间。
    // 此处设置的行数和列数,只是用来决定控件之间的相对位置
    layout->addWidget(button1, 0, 0);
    layout->addWidget(button2, 1, 1);
    layout->addWidget(button3, 2, 2);
    layout->addWidget(button4, 3, 3);


    this->setLayout(layout);
}

Widget::~Widget()
{
    delete ui;
}

在这里插入图片描述
我们可以看到创建的布局管理器,这里的控件尺寸都是均等的。

当需要创建出尺寸不同的控件的时候,就可以通过拉伸系数来设置。 拉伸系数就相当于设置控件间的尺寸的,“比例”。

3.2. 代码示例: 设置 QGridLayout 中元素的大小比例

#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QGridLayout>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 创建 6 个按钮,使用网格布局 2*3 的方式来布局
    QPushButton* button1 = new QPushButton("按钮1");
    QPushButton* button2 = new QPushButton("按钮2");
    QPushButton* button3 = new QPushButton("按钮3");
    QPushButton* button4 = new QPushButton("按钮4");
    QPushButton* button5 = new QPushButton("按钮5");
    QPushButton* button6 = new QPushButton("按钮6");

    // 创建网格布局管理器,把这些控件添加进去
    QGridLayout* layout = new QGridLayout();
    layout->addWidget(button1, 0, 0);
    layout->addWidget(button2, 0, 1);
    layout->addWidget(button3, 0, 2);
    layout->addWidget(button4, 1, 0);
    layout->addWidget(button5, 1, 1);
    layout->addWidget(button6, 1, 2);

    this->setLayout(layout);

    // 设置水平拉伸系数, 此处的代码含义,就是按照 1:1:2 的方式来设置宽度
    layout->setColumnStretch(0, 1); 
    layout->setColumnStretch(1, 1);
    layout->setColumnStretch(2, 2);
    // 如果把拉伸系数设为 0, 意思就是不参与拉伸,此时按钮的宽度就是固定值
}

Widget::~Widget()
{
    delete ui;
}

在这里插入图片描述

4. 表单布局

除了上述的布局管理器之外, Qt 还提供了 QFormLayout , 属于是 QGridLayout 的特殊情况, 专
门用于实现两列表单的布局。

这种表单布局多用于让用户填写信息的场景. 左侧列为提示, 右侧列为输⼊框。

4.1. 代码示例: 使用 QFormLayout 创建表单

前端中有一个form标签,搭配其它的 input 等标签,让网页端用户输入数据,并且提交到服务器。

#include "widget.h"
#include "ui_widget.h"
#include <QFormLayout>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

     // 设置成 3 行 2列
    QFormLayout* layout = new QFormLayout;
    this->setLayout(layout);

    // 创建 3个 label 作为第一列
    QLabel* label1 = new QLabel("姓名");
    QLabel* label2 = new QLabel("年龄");
    QLabel* label3 = new QLabel("电话");

    // 创建 3 个 label 作为第二列
    QLineEdit* edit1 = new QLineEdit("姓名");
    QLineEdit* edit2 = new QLineEdit("年龄");
    QLineEdit* edit3 = new QLineEdit("电话");

    // 把上述控件添加到表单布局中
    layout->addRow(label1, edit1);
    layout->addRow(label2, edit2);
    layout->addRow(label3, edit3);

    // 创建一个 "提交按钮"
    QPushButton* button = new QPushButton("提交");
    layout->addRow(nullptr, button);
}

Widget::~Widget()
{
    delete ui;
}

在这里插入图片描述

5. Spacer

使用布局管理器的时候,可能需要在控件之间,添加一段空白,就可以使用 QSpacerItem 来表示。
在这里插入图片描述

5.1. 代码示例: 创建⼀组左右排列的按钮

#include "widget.h"
#include "ui_widget.h"
#include <QHBoxLayout>
#include <QPushButton>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);


    QHBoxLayout* layout = new QHBoxLayout();
    this->setLayout(layout);

    QPushButton* button1 = new QPushButton("按键1");
    QPushButton* button2 = new QPushButton("按键2");

    // 创建 spacer 是两个按钮之间之间存在空白
    QSpacerItem* spacer = new QSpacerItem(200, 20);

    // 当前是要把空白添加到两个按钮之间, 此处 add 的顺序就是把 addSpaserItem 放到中间了
    layout->addWidget(button1);
    layout->addSpacerItem(spacer);
    layout->addWidget(button2);

}

Widget::~Widget()
{
    delete ui;
}

在这里插入图片描述
或者直接用这个:
在这里插入图片描述

总结:

通过本文的学习,我们了解到Qt框架中的布局管理器是构建高效、响应式用户界面的关键工具。垂直布局(QVBoxLayout)和水平布局(QHBoxLayout)为我们提供了基本的一维布局方案,而网格布局(QGridLayout)则允许我们在二维空间内灵活地排列控件。表单布局(QFormLayout)特别适合于创建需要用户输入信息的界面,它以两列的形式组织标签和输入控件。此外,Spacer(QSpacerItem)的使用可以在控件之间添加必要的间隔,以优化界面的视觉效果和用户体验。

每种布局管理器都具有其独特的用途和优势,通过合理地组合使用,我们可以创建出既美观又实用的用户界面。更重要的是,这些布局管理器支持控件的自适应调整,确保了界面在不同屏幕尺寸和分辨率下的一致性和可用性。通过本文的代码示例,开发者可以快速掌握Qt布局管理器的使用方法,并将其应用到自己的项目中,以提升应用的专业度和用户满意度。

到这里所有的控件都结束了!上述的每个控件,都是“可扩展的”,每个控件都是对应 Qt 内置的一个类,咱们在代码中都可以基于这个类,继承出你自定义的子类,在这个自定义的子类中,又可以添加很多的属性方法,实现自己的需求场景。还可以在子类中,把多个控件组合到一起。

  • 20
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Q_hd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值