Qt 学习(四) —— QGridLayout栅格布局

news2024/11/15 4:43:37

目录

      • 一、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<MyLayout *>(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()); ,其中,参数rowcolumn用以指定控件的位置,从0开始计数,rowSpancolumnSpan 指定从当前位置向右或向下所占的行和列数,如下:

原始布局,为了方便显示控件所占空间,将控件的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:

如果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());

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

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

void setOriginCorner(Qt::Corner);
Qt::Corner originCorner() const;

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

其中,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;

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/341042.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Git教程个人分享:如何将一个本地项目上传至远程仓库的流程

前言&#xff1a; 今天来分享一下&#xff0c;关于Git的一些教程&#xff0c;同时这也是我自己曾今学习Git时候的笔记&#xff0c;之所以更&#xff0c;也是方便后期自己可以去回顾&#xff0c;当然后面也会出一部分关于Git其他操作方面的内容。 这次我们分享的是&#xff0c…

基于JavaScript的Web端股票价格查看器——大道

&#x1f436; 基于JavaScript的Web端股票价格查看器——大道 一、项目背景 当下互联网发展迅速&#xff0c;互联网已经不断向传统金融领域渗透。在互联网上有大量金融领域的数据&#xff0c;如何利用好这些数据&#xff0c;对于投资者来说是十分重要的一件事情。股票价格实时…

JavaSE学习day4_01 循环for,while,do...while

1. 循环高级 1.1 无限循环 for、while、do...while都有无限循环的写法。 最为常用的是while格式的。 因为无限循环是不知道循环次数的&#xff0c;所以用while格式的 代码示例&#xff1a; while(true){} 1.2 跳转控制语句&#xff08;掌握&#xff09; 跳转控制语句&…

MySQL 插入数据

数据库与表创建成功以后&#xff0c;需要向数据库的表中插入数据。在 MySQL 中可以使用 INSERT 语句向数据库已有的表中插入一行或者多行元组数据。 你可以通过 mysql> 命令提示窗口中向数据表中插入数据&#xff0c;或者通过PHP脚本来插入数据。 语法 以下为向MySQL数据表…

51单片机——步进电机实验,小白讲解,相互学习

步进电机简介&#xff1a; 步进电机是将电脉冲信号转变为角位移或多线位移的开源控制元件。在非超载的情况下&#xff0c;电机的转速&#xff0c;停止的位置只取决于脉冲信号的频率和脉冲数&#xff0c;而不受负载变化的影响&#xff0c;即给电机加一个脉冲信号&#xff0c;电机…

Android - 自动系统签名

一、系统签名 以下是两类应用开发场景&#xff1a; 普通应用开发&#xff1a;使用公司自定义 keystore 进行签名&#xff0c;如&#xff1a;微信、支付宝系统应用开发&#xff1a;使用 AOSP 系统签名或厂商自定义 keystore 进行签名&#xff0c;如&#xff1a;设置、录音 系…

数学建模拓展内容:卡方检验和Fisher精确性检验(附有SPSS使用步骤)

卡方检验和Fisher精确性检验卡方拟合度检验卡方独立性检验卡方检验的前提假设Fisher精确性检验卡方拟合度检验 卡方拟合度检验概要&#xff1a;卡方拟合度检验也被称为单因素卡方检验&#xff0c;用于检验一个分类变量的预期频率和观察到的频率之间是否存在显著差异。 卡方拟…

第一部分:简单句——第二章:简单句的补充

简单句的核心构成&#xff1a;一主一谓 主语/宾语/表语 可以变成名词/代词/doing/to do 谓语动词有四种核心变化&#xff1a;三态 一否 时态语态情态否定 简单句的核心&#xff1a;将简单句给写对 简单句的补充&#xff1a;将简单句给写的更好、更充分 简单句的补充 1、限定…

计算机网络之HTTP04ECDHE握手解析

DH算法 离散读对数问题是DH算法的数学基础 &#xff08;1&#xff09;计算公钥 &#xff08;2&#xff09;交换公钥&#xff0c;并计算 对方公钥^我的私钥 mod p 离散对数的交换幂运算交换律使二者算出来的值一样&#xff0c;都为K k就是对称加密的秘钥 2. DHE算法 E&#…

DNS 原理入门指南(一)

DNS 是互联网核心协议之一。不管是上网浏览&#xff0c;还是编程开发&#xff0c;都需要了解一点它的知识。 本文详细介绍DNS的原理&#xff0c;以及如何运用工具软件观察它的运作。我的目标是&#xff0c;读完此文后&#xff0c;你就能完全理解DNS。 一、DNS 是什么&#xff1…

记录每日LeetCode 1138.字母板上的路径 Java实现

题目描述&#xff1a; 我们从一块字母板上的位置 (0, 0) 出发&#xff0c;该坐标对应的字符为 board[0][0]。 在本题里&#xff0c;字母板为board ["abcde", "fghij", "klmno", "pqrst", "uvwxy", "z"]&#x…

Linux重定向符、管道符讲解

目录 重定向 将命令与文件进行互动 输出重定向 输入重定向 管道符 将命令与命令互动起来 重定向 将命令与文件进行互动 重定向分类 一般情况下&#xff0c;Linux命令运行时都会打开一下三个文件 标准输入文件&#xff1a;stdin文件&#xff0c;文件描述符为0&#xff0c;Li…

自定义ESLint规则开发与使用

自定义eslint及使用 项目结构 |-eslint-plugin-demo //自定义eslint插件项目 | |-demo-app // 使用自定义eslint的测试应用 |-README.md 项目效果&#xff1a; github项目地址 自定义ESLint环境准备 安装脚手架 执行下列命令来安装开发eslint的脚手架。 yo(y…

中小学信息学相关编程比赛清单及报名网站汇总(C++类)

1、NOI系列比赛(CSP-J CSP-S NOIP NOI APIO CTSC IOI ISIJ等) NOI官网 NOI全国青少年信息学奥林匹克竞赛https://www.noi.cn/ 2、蓝桥杯青少年创意编程大赛 https://www.lanqiaoqingshao.cn/home 3、中国电子协会考评中心

数据结构 - Set 与 Map 接口介绍(TreeMap,HashMap,TreeSet,HashSet类)

文章目录前言1. Set / Map接口2. TreeSet类3. TreeMap 类4. HashSet 与 HashMap4.1 HashSet / HashMap 底层哈希表4.2 解决哈希冲突总结✨✨✨学习的道路很枯燥&#xff0c;希望我们能并肩走下来&#xff01; 编程真是一件很奇妙的东西。你只是浅尝辄止&#xff0c;那么只会觉得…

神经网络基础知识

神经网络基础知识 文章目录神经网络基础知识一、人工神经网络1.激活函数sigmod函数Tanh函数Leaky Relu函数分析2.过拟合和欠拟合二、学习与感知机1.损失函数与代价函数2. 线性回归和逻辑回归3. 监督学习与无监督学习三、优化1.梯度下降法2.随机梯度下降法(SGD)3. 批量梯度下降法…

JavaScript系列之new运算符

文章の目录一、什么是new&#xff1f;二、new经历了什么过程&#xff1f;三、new的过程分析四、其他作用参考写在最后一、什么是new&#xff1f; 众所周知&#xff0c;在JS中&#xff0c;new的作用是通过构造函数来创建一个实例对象。 像下面这样&#xff1a;&#xff08;和普…

Centos篇-Centos Minimal安装

安装Centos Minimal 下载镜像 由于使用Centos主要是安装K8s以及使用K8s或者docker安装各种服务&#xff0c;可以理解为就是单纯的服务器使用&#xff0c;所以不需要GUI&#xff0c;直接使用Centos的Server版本。 所以选择centos的minimal版本进行下载&#xff1a; 地址&#…

FreeRTOS队列集、事件标志组 | FreeRTOS十一

目录 说明&#xff1a; 一、队列集 1.1、队列集简介 1.2、队列集作用 二、队列集相关API函数 2.1、创建队列集函数 2.2、往队列集添加队列函数 2.3、队列集移除队列函数 2.4、获取队列集中有有效队列 三、事件标志组 3.1、什么是事件标志组 3.2、事件标志组的特点 …

Matlab傅里叶谱方法求解二维波动方程

傅里叶谱方法求解基本偏微分方程—二维波动方程 二维波动方程 将一维波动方程中的一维无界弦自由振动方程推广到二维空间上, 就得到了描述无界 (−∞<x,y<∞)(-\infty<x, y<\infty)(−∞<x,y<∞) 弹性薄膜的波动方程: ∂2u∂t2a2(∂2∂x2∂2∂y2)u(1)\frac…