当前位置:   article > 正文

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

qgridlayout

Qt系列教程总目录

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

在这里插入图片描述

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

一、QGridLayout布局规则

QBoxLayout类似,详见 QBoxLayout布局规则

二、创建QGridLayout

QGridLayout只有一个构造函数

explicit QGridLayout(QWidget *parent = nullptr);
  • 1

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

由于布局是默认铺满父级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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

三、成员函数

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; // 获取两个方向的间距
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
2. 可拉伸控件(弹簧)

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

void setRowStretch(int row, int stretch); // 设置指定行的弹簧系数
void setColumnStretch(int column, int stretch); // 设置指定列的弹簧系数
int rowStretch(int row) const; // 获取指定行的弹簧系数
int columnStretch(int column) const; // 获取指定列的弹簧系数
  • 1
  • 2
  • 3
  • 4
3. 最小行高/列宽
void setRowMinimumHeight(int row, int minSize); // 设置最小行高
void setColumnMinimumWidth(int column, int minSize); // 设置最小列宽
int rowMinimumHeight(int row) const; // 获取最小行高
int columnMinimumWidth(int column) const; // 获取最小列宽
  • 1
  • 2
  • 3
  • 4
4. 行数和列数
int columnCount() const; // 获取列数
int rowCount() const; // 获取行数
  • 1
  • 2
5. 锁定纵横比

根据宽度计算高度

bool hasHeightForWidth() const override; 
int heightForWidth(int) const override;
int minimumHeightForWidth(int) const override;
  • 1
  • 2
  • 3

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

bool QLayoutItem::hasHeightForWidth() const
{
    return false;
}

int QLayoutItem::heightForWidth(int /* w */) const
{
    return -1;
}

int QLayoutItem::minimumHeightForWidth(int w) const
{
    return heightForWidth(w);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

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

 int MyLayout::heightForWidth(int w) const
 {
     if (cache_dirty || cached_width != w) {
         MyLayout *that = const_cast<MyLayout *>(this);
         int h = calculateHeightForWidth(w);
         that->cached_hfw = h;
         return h;
     }
     return cached_hfw;
 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
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());
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

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

在这里插入图片描述

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

在这里插入图片描述

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

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

在这里插入图片描述

示例1:

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

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

在这里插入图片描述

示例2:

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

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

在这里插入图片描述

示例3:

如果rowSpancolumnSpan-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());
  • 1
  • 2

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

8. 设置栅格布局原点位置
void setOriginCorner(Qt::Corner);
Qt::Corner originCorner() const;
  • 1
  • 2

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

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

enum Corner {
    TopLeftCorner = 0x00000,
    TopRightCorner = 0x00001,
    BottomLeftCorner = 0x00002,
    BottomRightCorner = 0x00003
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
枚举描述
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;
  • 1
  • 2

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

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

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

在这里插入图片描述

行列方式:

在这里插入图片描述

9.2 删除布局项
QLayoutItem *takeAt(int index) override;
  • 1

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

在这里插入图片描述

9.3 通过索引获取布局项位置信息
void getItemPosition(int idx, int *row, int *column, int *rowSpan, int *columnSpan) const;
  • 1

在这里插入图片描述

9.4 获取布局项数量
int count() const override;
  • 1

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/295599
推荐阅读
相关标签
  

闽ICP备14008679号