七、布局管理和空间间隔

七、布局管理和空间间隔

  • Vertical Layout:垂直布局
  • Horizontal Layout:横向布局
  • Grid Layout:网格布局
  • Form Layout:表单布局
  • Horizontal Spacer:水平间隔
  • Vertical Spacer:垂直间隔

我们重点介绍代码实现的布局,GridLayout网格布局和FormLayout表单布局

7.1 QGridLayout 网格布局

首先我们创建QWidget工程

widget.h头文件

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include<QGridLayout> //网格控件
#include<QLabel> //标签控件
#include<QPushButton> //命令按钮控件


QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    
    QGridLayout *gl;
    
    QPushButton *pb1;
    QPushButton *pb2;
    QPushButton *pb3;
    QPushButton *pb4;

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

首先我们引入三个头文件分别是网格布局控件QGridLayout、标签控件QLabel和命令按钮控件QPushButton,QLabel和QPushButton后面会详细介绍,我们这里只要知道这两个是控制标签和命令按钮的就行。

创建一个QGridLayout对象用于在源文件中进行网格布局和四个QPushButton对象用于在源文件中进行命令按钮。

widget.cpp源文件

#include "widget.h"
#include "ui_widget.h"

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

    pb1=new QPushButton(this);
    pb1->setText("第一区:顶部菜单栏选项");
    pb1->setFixedHeight(40); //设置高度
    pb1->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
    /*
    QSizePolicy
    此属性包含小部件的默认布局行为
    如果有一个QLayout管理这个小部件的子部件,
    则使用该布局指定的大小策略。如果没有这样的QLayout,则使用该函数的结果。
    默认策略是Preferred/Preferred,
    这意味着小部件可以自由调整大小,
    但更倾向于使用sizeHint()返回的大小。
    类似按钮的小部件设置大小策略,
    以指定它们可以水平拉伸,但垂直固定。
    这同样适用于lineedit控件
    (如QLineEdit、QSpinBox或可编辑的QComboBox)和其他控件
    */
    pb2=new QPushButton(this);
    pb2->setText("第二区:侧边栏选项");
    pb2->setFixedWidth(100); //设置宽度
    pb2->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);

    pb3=new QPushButton(this);
    pb3->setText("第三区:底部选项");
    pb3->setFixedHeight(40);
    pb3->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);

    pb4=new QPushButton(this);
    pb4->setText("第四区:子窗体选项");
    pb4->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);


    gl=new QGridLayout();
    gl->setContentsMargins(0,0,0,0);
    /*
     setContentsMargins
     设置要围绕布局使用的左、上、右和下边距。
     默认情况下,QLayout使用样式提供的值。在大多数平台上,所有方向的边距都是11像素。
     */
    //gl->setMargin(30);
    /*
     * 设置控件与窗体的左右边距
     * 这个功能已经过时了。提供它是为了保持旧源代码的工作。我们强烈建议不要在新代码中使用它。
     */
    gl->setSpacing(0);
    /*
     * 各个控件之间的上下间距
     * 此函数将垂直和水平间距设置为spacing。
     */

    gl->addWidget(pb1,0,1);
    gl->addWidget(pb2,0,0,3,1);
    gl->addWidget(pb3,2,1);
    gl->addWidget(pb4,1,1);
    /*
    *addWidget(QWidget * widget, int fromRow, int fromColumn, int rowSpan, int columnSpan,
    Qt::Alignment alignment = 0)
    QWidget * widget:需要添加的widget
    int fromRow:所在行
    int fromColumn:所在列
    int rowSpan:所占行数
    int columnSpan:所占列数
    alignment:对齐方式
    */

    setLayout(gl);
    /*
     * 将此小部件的布局管理器设置为layout。
    如果这个小部件上已经安装了布局管理器,
    那么QWidget将不允许您安装其他布局管理器。
    您必须首先删除现有的布局管理器(由layout()返回),
    然后才能使用新布局调用setLayout()。
    如果layout是另一个小部件上的布局管理器,
    setLayout()将表示该布局并使其成为该小部件的布局管理器。
    */
}

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

详解上面涉及到的函数:

void QWidget::setFixedHeight(int h):

在不改变宽度的情况下,将小部件的最小高度和最大高度设置为h。

与此同时还有其他函数:

void QWidget::setFixedSize(const QSize &s):将小部件的最小和最大尺寸设置为s,从而防止它不断增长或缩小。

void QWidget::setFixedSize(int w, int h):将小部件的宽度设置为w,高度设置为h。

void QWidget::setFixedWidth(int w):在不改变高度的情况下,将小部件的最小和最大宽度设置为w。

void QWidget::setSizePolicy(QSizePolicy::Policy horizontal, QSizePolicy::Policy vertical):

将小部件的大小策略设置为水平和垂直,具有标准拉伸,没有高度换宽度。

对于QSizePolicy::Policy的参数QT提供七种参数:

QSizePolicy::Policy
常量描述

QSizePolicy::Fixed

0QWidget::sizeHint()是唯一可接受的替代方法,因此小部件永远不能增长或缩小(例如,按钮的垂直方向)。

QSizePolicy::Minimum

GrowFlag

sizeHint()是最小的,也是足够的。小部件可以扩展,但它变大没有好处(例如,按钮的水平方向)。它不能小于sizeHint()提供的大小。

QSizePolicy::Maximum

ShrinkFlag

sizeHint()是一个最大值。如果其他部件需要空间(例如分隔线),则小部件可以任意缩小而不会损害。它不能大于sizeHint()提供的大小。

QSizePolicy::Preferred

GrowFlag | ShrinkFlag

sizeHint()是最好的,但是小部件可以缩小,但仍然有用。小部件可以展开,但是它比sizeHint()(默认的QWidget策略)大

QSizePolicy::Expanding

GrowFlag | ShrinkFlag | ExpandFlag

sizeHint()是一个合理的大小,但是小部件可以缩小并且仍然有用。小部件可以利用额外的空间,所以它应该得到尽可能多的空间(例如,水平滑块的水平方向)。

QSizePolicy::MinimumExpanding

GrowFlag | ExpandFlag

sizeHint()是最小的,也是足够的。小部件可以利用额外的空间,所以它应该得到尽可能多的空间(例如,水平滑块的水平方向)。

QSizePolicy::Ignored

ShrinkFlag | GrowFlag | IgnoreFlag

sizeHint()被忽略。小部件将获得尽可能多的空间。

在这个例子中,我们用到的是Expanding参数,意思就是能占多大空间就占多大空间,并且可以缩小,但是实际我们运行发现并不能把按钮缩小,这是因为官方说的小部件可以缩小,是把窗口变小,这些控件才会跟着缩小。

如果我们把下面代码注释掉

pb4->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);

 则运行结果为

我们发现这些控件并不紧凑在一起了。

void QLayout::setContentsMargins(int left, int top, int right, int bottom):

设置要围绕布局使用的左、上、右和下边距。默认情况下,QLayout使用样式提供的值。在大多数平台上,所有方向的边距都是11像素。

如果我们改为这样:

gl->setContentsMargins(20,20,20,20);

void QLayout::setMargin(int margin):

设置控件的与窗体的边距。这个功能已经过时了。提供它是为了保持旧源代码的工作。我们强烈建议不要在新代码中使用它。

void QGridLayout::setSpacing(int spacing):

设置各个控件的上下水平间距。

void QGridLayout::addWidget(QWidget * widget, int fromRow, int fromColumn, int rowSpan, int columnSpan, Qt::Alignment alignment = 0):

QWidget * widget:需要添加的widget

int fromRow:所在行

int fromColumn:所在列

int rowSpan:所占行数

int columnSpan:所占列数

alignment:对齐方式

void QWidget::setLayout(QLayout *layout):

将此小部件的布局管理器设置为layout。如果这个小部件上已经安装了布局管理器,那么QWidget将不允许您安装其他布局管理器。您必须首先删除现有的布局管理器(由layout()返回),然后才能使用新布局调用setLayout()。如果layout是另一个小部件上的布局管理器,setLayout()将表示该布局并使其成为该小部件的布局管理器。

总结:setLayout()函数是Qt中的一个函数,用于设置QWidget中的布局管理器。它接受一个QLayout对象作为参数,并将该布局管理器应用于QWidget。

7.2 QFormLayout 表单布局

首先我们创建widget工程

Widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include<QFormLayout>
#include<QLineEdit>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    
    QFormLayout *fl;
    QLineEdit *le1;
    QLineEdit *le2;
    QLineEdit *le3;

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

引入QFormLayout表单布局头文件和QLineEdit编辑头文件。

widget.cpp

#include "widget.h"
#include "ui_widget.h"

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

    setFixedSize(250,250);

    fl=new QFormLayout(this);
    le1=new QLineEdit(); //输入学号
    le2=new QLineEdit(); //输入姓名
    le3=new QLineEdit(); //输入学校

    fl->addRow("学号",le1);
    fl->addRow("姓名",le2);
    fl->addRow("学校",le3);
    fl->setSpacing(20);
    
    //把标签单独显示一行
    //fl->setRowWrapPolicy(QFormLayout::WrapAllRows);

    //把标签和输入框显示在一行
    fl->setRowWrapPolicy(QFormLayout::WrapLongRows);

    //把标签对齐
    fl->setLabelAlignment(Qt::AlignLeft);

}

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

下面详解上面涉及到的函数 

void QFormLayout::addRow(QWidget *label, QWidget *field):

在此表单布局的底部添加具有给定标签和字段的新行。


void setRowWrapPolicy(QFormLayout::RowWrapPolicy policy):

它来自RowWrapPolicy

此属性保留表单的行换行方式

默认值取决于小部件或应用程序样式。对于Qt扩展样式,默认是WrapLongRows;对于其他样式,默认是DontWrapRows。如果您希望将每个标签显示在其关联字段的上方(而不是旁边),请将此属性设置为WrapAllRows。

关于QFormLayout::RowWrapPolicy,Qt给出了三种参数

QFormLayout::RowWrapPolicy
常量描述

QFormLayout::DontWrapRows

0字段总是放在它们的标签旁边。这是除了Qt扩展样式之外的所有样式的默认策略。

QFormLayout::WrapLongRows

1标签被赋予足够的水平空间来容纳最宽的标签,其余的空间留给字段。如果字段对的最小大小大于可用空间,则将字段换行到下一行。这是Qt扩展样式的默认策略。

QFormLayout::WrapAllRows

2字段总是布局在它们的标签下面


void setLabelAlignment(Qt::Alignment alignment):

它来自Qt::Alignment

此属性保持标签的水平对齐
默认值取决于小部件或应用程序样式。对于QCommonStyle派生的样式,除了QPlastiqueStyle,默认是Qt::AlignLeft;对于其他样式,默认是Qt::AlignRight。

关于Qt::Alignment,Qt也给出很多参数

横坐标
常量描述

Qt::AlignLeft

0x0001

与左边缘对齐。

Qt::AlignRight

0x0002

与右边缘对齐。

Qt::AlignHCenter

0x0004

在可用空间中水平居中。

Qt::AlignJustify

0x0008

对可用空间中的文本进行校验。
纵坐标
常量描述

Qt::AlignTop

0x0020

与顶部对齐。

Qt::AlignBottom

0x0040

与底部对齐。

Qt::AlignVCenter

0x0080

在可用空间中垂直居中。

Qt::AlignBaseline

0x0100

与基线对齐。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Mo Yan

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

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

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

打赏作者

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

抵扣说明:

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

余额充值