[Qt 教程之Widgets模块] —— QGridLayout栅格布局

2025-07-30 14:55:17
Avatar for adminadmin

Qt系列教程总目录

文章目录

一、QGridLayout布局规则二、创建QGridLayout三、成员函数1. 控件间距2. 可拉伸控件(弹簧)3. 最小行高/列宽4. 行数和列数5. 锁定纵横比6. 添加控件7. 添加布局8. 设置栅格布局原点位置9. 操作布局项9.1 访问布局项9.2 删除布局项9.3 通过索引获取布局项位置信息9.4 获取布局项数量

与QBoxLayout只能在一个方向布局不同,QGridLayout可以在网格中布局(垂直和水平两个方向)。

这里仅以按钮为例,布局也可用于其他控件。

一、QGridLayout布局规则

与QBoxLayout类似,详见 QBoxLayout布局规则

二、创建QGridLayout

QGridLayout只有一个构造函数

explicit QGridLayout(QWidget *parent = nullptr);

可以通过拖动控件创建,也可以使用代码直接创建

由于布局是默认铺满父级Widget的,为了方便控制布局的整体大小,一般不是将最外层的Widget窗口传给QGridLayout,而是再新建一个Widget,如下:

// 创建指针

QWidget *gridLayoutWidget;

QGridLayout *gridLayout;

// 创建新Widget

gridLayoutWidget = new QWidget(Widget);

// 为新Widget设置大小

gridLayoutWidget->setGeometry(QRect(149, 80, 321, 191));

// 实例化布局对象,并将新Widget传入

gridLayout = new QGridLayout(gridLayoutWidget);

三、成员函数

1. 控件间距

和QBoxLayout类似,QGridLayout也有间距的概念,不同是QGridLayout可以设置两个方向的间距,如下:

void setHorizontalSpacing(int spacing); // 设置水平方向的间距

int horizontalSpacing() const; // 获取水平方向的间距

void setVerticalSpacing(int spacing); // 设置垂直方向的间距

int verticalSpacing() const; // 获取处置方向的间距

void setSpacing(int spacing) override; // 设置两个方向的间距

int spacing() const override; // 获取两个方向的间距

2. 可拉伸控件(弹簧)

同样和QBoxLayout类似,参考 可拉伸控件 ,相关函数如下:

void setRowStretch(int row, int stretch); // 设置指定行的弹簧系数

void setColumnStretch(int column, int stretch); // 设置指定列的弹簧系数

int rowStretch(int row) const; // 获取指定行的弹簧系数

int columnStretch(int column) const; // 获取指定列的弹簧系数

3. 最小行高/列宽

void setRowMinimumHeight(int row, int minSize); // 设置最小行高

void setColumnMinimumWidth(int column, int minSize); // 设置最小列宽

int rowMinimumHeight(int row) const; // 获取最小行高

int columnMinimumWidth(int column) const; // 获取最小列宽

4. 行数和列数

int columnCount() const; // 获取列数

int rowCount() const; // 获取行数

5. 锁定纵横比

根据宽度计算高度

bool hasHeightForWidth() const override;

int heightForWidth(int) const override;

int minimumHeightForWidth(int) const override;

这三个函数默认是没有实际功能的,如要使用,需要自己重载实现,他们的源码如下:

bool QLayoutItem::hasHeightForWidth() const

{

return false;

}

int QLayoutItem::heightForWidth(int /* w */) const

{

return -1;

}

int QLayoutItem::minimumHeightForWidth(int w) const

{

return heightForWidth(w);

}

官方给出了重载的例子,如下:

int MyLayout::heightForWidth(int w) const

{

if (cache_dirty || cached_width != w) {

MyLayout *that = const_cast(this);

int h = calculateHeightForWidth(w);

that->cached_hfw = h;

return h;

}

return cached_hfw;

}

6. 添加控件

// 在控件队列最后面添加一个新控件

inline void addWidget(QWidget *w) { QLayout::addWidget(w); }

// 在布局的指定位置添加一个新控件

void addWidget(QWidget *, int row, int column, Qt::Alignment = Qt::Alignment());

// 在布局的指定位置添加一个新控件,并可指定跨行/列

void addWidget(QWidget *, int row, int column, int rowSpan, int columnSpan, Qt::Alignment = Qt::Alignment());

其中,inline void addWidget(QWidget *w) { QLayout::addWidget(w); } 如果队列中间有空的位置,也会忽略过,只会在队列最后添加新控件,如下:

第三行第二列空出一个位置,添加控件后,跳过了该位置,如下:

如果想一个控件占多行/列,可以使用函数void addWidget(QWidget *, int row, int column, int rowSpan, int columnSpan, Qt::Alignment = Qt::Alignment()); ,其中,参数row和column用以指定控件的位置,从0开始计数,rowSpan和columnSpan 指定从当前位置向右或向下所占的行和列数,如下:

原始布局,为了方便显示控件所占空间,将控件的sizePolicy设置为Expanding,使其充满布局单元格(关于sizePolicy详见QGridLayout布局规则):

示例1:

在(2, 0)的位置添加行控件,所占空间为1行1列,如下:

ui->gridLayout->addWidget(btn, 2, 0, 1, 1);

示例2:

在(2, 0)的位置添加行控件,所占空间为2行1列,如下:

ui->gridLayout->addWidget(btn, 2, 0, 2, 1);

示例3:

如果rowSpan和columnSpan 为-1,则控件所占控件一直延申到最右和最底部边界,如下:

7. 添加布局

void addLayout(QLayout *, int row, int column, Qt::Alignment = Qt::Alignment());

void addLayout(QLayout *, int row, int column, int rowSpan, int columnSpan, Qt::Alignment = Qt::Alignment());

布局中还能嵌套布局,函数入参与使用方法和addWidget类似,这里不再赘述。

8. 设置栅格布局原点位置

void setOriginCorner(Qt::Corner);

Qt::Corner originCorner() const;

和QBoxLayout的Direction类似,设置布局中控件的排列方向。

其中,Qt::Corner是一个枚举如下:

enum Corner {

TopLeftCorner = 0x00000,

TopRightCorner = 0x00001,

BottomLeftCorner = 0x00002,

BottomRightCorner = 0x00003

};

枚举值描述Qt::TopLeftCorner0x00000矩形的左上角Qt::TopRightCorner0x00001矩形的右上角Qt::BottomLeftCorner0x00002矩形的左下角Qt::BottomRightCorner0x00003矩形的右上角

布局原点默认为Qt::TopLeftCorner左上角,如下图:

右上角如下图,其他方向同理:

9. 操作布局项

Qt提供了一个布局项的抽象类QLayoutItem ,提供了对布局中单元格的操作。

这里仅介绍QGridLayout直接涉及到的几个方法,关于QLayoutItem 更详细的描述见

9.1 访问布局项

QLayoutItem *itemAt(int index) const override;

QLayoutItem *itemAtPosition(int row, int column) const;

可以通过索引访问,也可以通过所在行列位置访问。

默认计数都是从0开始,需要注意的是,index的方式是从远离原点的位置开始计数,行列定位的则是从靠近原点的位置开始计数,如下:

index方式:(测试发现的,不知道为什么要这么设计,和习惯用法不同,如果你知道原因欢迎评论区留言)

行列方式:

9.2 删除布局项

QLayoutItem *takeAt(int index) override;

这个只能通过索引定位,索引计数方法同上。

9.3 通过索引获取布局项位置信息

void getItemPosition(int idx, int *row, int *column, int *rowSpan, int *columnSpan) const;

9.4 获取布局项数量

int count() const override;

Copyright © 2088 沙滩足球世界杯_足球世界杯中国 - pfw18.com All Rights Reserved.
友情链接