Qt_布局管理器

news2024/11/15 9:30:30

目录

1、QVBoxLayout垂直布局

1.1 QVBoxLayout的使用

1.2 多个布局管理器 

2、QHBoxLayout水平布局 

2.1 QHBoxLayout的使用

2.2 嵌套的Layout 

3、QGridLayout网格布局 

3.1  QGridLayout的使用

3.2 设置控件大小比例 

4、QFormLayout 

4.1  QFormLayout的使用

5、QSpacerItem 

5.1 QSpacerItem的使用

结语 


前言:

        使用Qt时,在没有布局管理器(Layout)概念之前,在界面上创建控件都是用“绝对定位”来设置的,即调用setGeometry或move函数摆放,或者直接在ui文件中对控件进行手动的摆放,这些方式都会导致界面上的控件摆放存在偏差,影响整体美观。因此引入布局管理器机制,将界面上的控件都直接放到布局管理器下,布局管理器会自动对这些控件进行位置大小的调整,让整个界面看起来更加规整。

1、QVBoxLayout垂直布局

         QVBoxLayout表示垂直布局管理器,他也是一个控件,只不过该控件的作用是对内部的其他控件进行规整摆放。QVBoxLayout属性介绍如下:

layoutLeftMargin
左侧边距
layoutRightMargin
右侧边距
layoutTopMargin
上方边距
layoutBottomMargin
下方边距
layoutSpacing
相邻元素之间的间距

        与QVBoxLayout相关的常用接口:

addWidget(QWidget*)
把控件添加到布局管理器中
setLayout(QLayout*)是QWidget的接口,用于将布局管理器设置到widget下

1.1 QVBoxLayout的使用

        创建一个QVBoxLayout和三个按钮控件,将三个按钮控件放到该QVBoxLayout下,观察生成后的界面,代码如下:

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

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

    QVBoxLayout* qv = new QVBoxLayout();//创建垂直布局管理器

    //创建三个按钮
    QPushButton* qp1 = new QPushButton("按钮1");
    QPushButton* qp2 = new QPushButton("按钮2");
    QPushButton* qp3 = new QPushButton("按钮3");

    //将三个按钮放到管理器下
    qv->addWidget(qp1);
    qv->addWidget(qp2);
    qv->addWidget(qp3);

    //将管理器设置到当前widge下
    this->setLayout(qv);

}

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

        运行结果:

        从结果可以发现三个按钮规章有序的显示在界面上,并且对widget界面进行拉伸时,这三个按钮也会跟着拉伸的比例变化,如果这三个按钮直接放到widget界面上,则按钮尺寸不会随着widget界面的尺寸变化而变化。能够实现这个效果的原因是布局管理器作用在widget上,换句话说,一个widget只能有一个布局管理器并且布局管理器就是widget本身,所以对widget界面进行尺寸拉伸时,实际上就是对布局管理器做拉伸,进而导致布局管理器里的控件也跟着拉伸了

1.2 多个布局管理器 

        虽然一个widget下只能有一个布局管理器,但是可以通过ui文件中界面创建的方式在一个widget下生成多个布局管理器,操作如下:

        但是在运行程序后,发现对最终的界面进行拖拽则无法影响界面上的按钮,如下图:

        原因是通过ui文件手动式创建的Layout,实际上是先创建了一个widget,然后再将创建的Layout放到该widget下,所以上述界面中有3个widget,而我们拖拽的是最外层的widget尺寸,不会影响里面两个widget的尺寸,也就不会影响Layout里的按钮的尺寸了。

2、QHBoxLayout水平布局 

         QHBoxLayout表示水平布局管理器,他的作用和QVBoxLayout是一样的,不过他是在水平方向摆放控件的,QHBoxLayout效果图如下:

        QHBoxLayout属性以及常用接口都和QVBoxLayout一样,因此这里就不再介绍了。

2.1 QHBoxLayout的使用

        创建一个QHBoxLayout和三个按钮控件,将三个按钮控件放到该QHBoxLayout下,观察生成后的界面,代码如下:

#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* qh = new QHBoxLayout();

    //创建三个按钮
    QPushButton* q1 = new QPushButton("按钮1");
    QPushButton* q2 = new QPushButton("按钮2");
    QPushButton* q3 = new QPushButton("按钮3");

    //将按钮添加到管理器中
    qh->addWidget(q1);
    qh->addWidget(q2);
    qh->addWidget(q3);

    //将管理器设置进当前widget中
    this->setLayout(qh);
}

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

        运行结果:

2.2 嵌套的Layout 

        在上述水平布局管理中添加一个垂直布局管理器,观察最终的现象,代码如下:

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

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

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

    //创建三个按钮
    QPushButton* q1 = new QPushButton("按钮1");
    QPushButton* q2 = new QPushButton("按钮2");
    QPushButton* q3 = new QPushButton("按钮3");

    //将按钮添加到管理器中
    qh->addWidget(q1);
    qh->addWidget(q2);
    qh->addWidget(q3);

    //将管理器设置进当前widget中
    this->setLayout(qh);

    //创建小Layout-垂直管理器
    QVBoxLayout* qh1 = new QVBoxLayout();

    //创建三个按钮
    QPushButton* q4 = new QPushButton("按钮4");
    QPushButton* q5 = new QPushButton("按钮5");
    QPushButton* q6 = new QPushButton("按钮6");

    //将按钮添加到小的垂直管理器中
    qh1->addWidget(q4);
    qh1->addWidget(q5);
    qh1->addWidget(q6);

    //将小垂直管理器添加到水平管理器中
    qh->addLayout(qh1);

}

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

         运行结果:

        从上述的例子中可以总结一点:垂直布局管理器的控件添加方式是从下往上式的添加,而水平布局管理器是从右往左式的添加控件。 

3、QGridLayout网格布局 

         QGridLayout表示网格布局,通俗来说就是水平和垂直布局的结合版,就如同一个二维数组,内部的控件就是数值上的元素。QGridLayout属性相比于上述两个控件的区别是:

layoutHorizontalSpacing
相邻元素之间⽔平⽅向的间距
layoutVerticalSpacing
相邻元素之间垂直⽅向的间距
layoutRowStretch
⾏⽅向的拉伸系数
layoutColumnStretch
列⽅向的拉伸系数

        QGridLayout的常用接口和上述两个控件也几乎相同。

3.1  QGridLayout的使用

        创建一个QGridLayout和四个按钮控件,将这四个按钮控件放到QGridLayout下,观察生成的界面,代码如下:

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

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

    //创建QGridLayout
    QGridLayout* qg = new QGridLayout();

    //创建四个按钮
    QPushButton* p1 = new QPushButton("按钮1");
    QPushButton* p2 = new QPushButton("按钮2");
    QPushButton* p3 = new QPushButton("按钮3");
    QPushButton* p4 = new QPushButton("按钮4");

    //将按钮添加到QGridLayout中,注意表明出坐标
    qg->addWidget(p1,0,0);
    qg->addWidget(p2,0,1);
    qg->addWidget(p3,1,0);
    qg->addWidget(p4,1,1);

    this->setLayout(qg);

}

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

        运行结果:

        可以从结果看到,界面上既能完成垂直布局,又能完成水平布局。

3.2 设置控件大小比例 

        在QGridLayout中,可以设置以行、列为单位设置控件的拉伸系数,比如调用函数setColumnStretch就是设置列上所有控件的拉伸系数,调用函数setRowStretch就是设置行上所有控件的拉伸系数。注意设置拉伸系数不等于直接设置尺寸,拉伸系数表示与当前单位与其他单位的长度比例。例子如下:

        ①设置列拉伸(水平方向拉伸控件):

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

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

    //创建QGridLayout
    QGridLayout* qg = new QGridLayout();

    //创建四个按钮
    QPushButton* p1 = new QPushButton("按钮1");
    QPushButton* p2 = new QPushButton("按钮2");
    QPushButton* p3 = new QPushButton("按钮3");
    QPushButton* p4 = new QPushButton("按钮4");

    //将按钮添加到QGridLayout中,注意表明出坐标
    qg->addWidget(p1,0,0);
    qg->addWidget(p2,0,1);
    qg->addWidget(p3,1,0);
    qg->addWidget(p4,1,1);

    this->setLayout(qg);

    qg->setColumnStretch(0,1);//设置该列的拉伸系数是1
    qg->setColumnStretch(1,3);//设置该列的拉伸系数是3
    //则该第1列的长度是第0列的三倍
}

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

        运行结果:

        结果是第1列的长度是第0列的三倍。


        ②设置列拉伸(垂直方向拉伸控件):

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

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

    //创建QGridLayout
    QGridLayout* qg = new QGridLayout();

    //创建四个按钮
    QPushButton* p1 = new QPushButton("按钮1");
    QPushButton* p2 = new QPushButton("按钮2");
    QPushButton* p3 = new QPushButton("按钮3");
    QPushButton* p4 = new QPushButton("按钮4");
    //因为每个按钮的垂直尺寸是固定的,因此要手动将按钮的垂直属性设置为拓展,目的是方便观察
    p1->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Expanding);
    p2->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Expanding);
    p3->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Expanding);
    p4->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Expanding);

    //将按钮添加到QGridLayout中,注意表明出坐标
    qg->addWidget(p1,0,0);
    qg->addWidget(p2,0,1);
    qg->addWidget(p3,1,0);
    qg->addWidget(p4,1,1);

    this->setLayout(qg);

    qg->setRowStretch(0,1);//设置该行的拉伸系数是1
    qg->setRowStretch(1,3);//设置该行的拉伸系数是3
    //则该第1行的长度是第0行的三倍
}

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

        运行结果:

4、QFormLayout 

        QFormLayout表示表单布局,QFormLayout的功能就比较单一了,他是专门实现只有两列的表单,可以看成是QGridLayout的一个分支控件,因此QFormLayout的属性和QGridLayout几乎一样,只是QFormLayout的添加控件接口为addRow,该接口介绍如下:

void addRow(QWidget *label, QWidget *field);
// 第⼀个控件固定是QLabel, 第⼆个控件可以是任意控件
// 如果把第⼀个参数填写为NULL, 则第一列什么都不显⽰,但是第二个参数不能为空

4.1  QFormLayout的使用

        QFormLayout常用于填写信息的场景, 因此模拟一个信息表单,首先创建一个QFormLayout ,和三个QLabel以及三个QLineEdit,实现代码如下:

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

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

    //创建QFormLayout
    QFormLayout* qf = new QFormLayout;

    //创建三对QLabel和QLineEdit
    QLabel* q1 = new QLabel("姓名");
    QLabel* q2 = new QLabel("电话");
    QLabel* q3 = new QLabel("地址");

    QLineEdit* ql1 = new QLineEdit;
    QLineEdit* ql2 = new QLineEdit;
    QLineEdit* ql3 = new QLineEdit;

    //创建提交按钮
    QPushButton* qp = new QPushButton("提交");

    //将上述控件添加到QFormLayout中
    qf->addRow(q1,ql1);
    qf->addRow(q2,ql2);
    qf->addRow(q3,ql3);
    qf->addRow(nullptr,qp);

    this->setLayout(qf);
}

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

        运行结果:

5、QSpacerItem 

        QSpacerItem表示一段空白,他的作用是在使⽤布局管理器的时候,可能需要在控件之间添加⼀段空⽩,这时候就可以用QSpacerItem了。QSpacerItem属性介绍如下:

width
QSpacerItem的 宽度
height
QSpacerItem的 ⾼度
hData
拉伸时,⽔平⽅向的 sizePolicy 的布局设置
vData
拉伸时, 垂直⽅向的 sizePolicy 的布局设置

5.1 QSpacerItem的使用

        创建一个布局管理器,和两个按钮控件以及一个QSpacerItem,观察没有QSpacerItem的界面和有QSpacerItem的界面的区别,代码如下:

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

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

    //创建一个布局管理器(水平或垂直都行)
    QHBoxLayout* qh = new QHBoxLayout();

    //创建两个按钮
    QPushButton* qp1 = new QPushButton("按钮1");
    QPushButton* qp2 = new QPushButton("按钮2");

    //创建QSpacerItem
    QSpacerItem* qs = new QSpacerItem(100,1);//初始化长、宽

    //将按钮放入布局管理器中
    qh->addWidget(qp1);
    qh->addSpacerItem(qs);
    qh->addWidget(qp2);

    this->setLayout(qh);
}

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

         测试结果:

结语 

        以上就是关于布局管理器的讲解,布局管理器整体使用难度不高,但他却是Qt开发中较为重要的一个控件,因为他保证了界面的规整度,同时也方便了开发者对控件规划的位置计算。

        最后如果本文有遗漏或者有误的地方欢迎大家在评论区补充,谢谢大家!!     

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

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

相关文章

【2024】前端学习笔记8-内外边距-边框-背景

学习笔记 外边距&#xff1a;Margin内边距&#xff1a;Padding边框&#xff1a;Border背景&#xff1a;Background 外边距&#xff1a;Margin 用于控制元素周围的空间&#xff0c;它在元素边框之外创建空白区域&#xff0c;可用于调整元素与相邻元素&#xff08;包括父元素和兄…

AI预测福彩3D采取888=3策略+和值012路或胆码测试9月19日新模型预测第92弹

经过90多期的测试&#xff0c;当然有很多彩友也一直在观察我每天发的预测结果&#xff0c;得到了一个非常有价值的信息&#xff0c;那就是9码定位的命中率非常高&#xff0c;90多期一共只错了10次&#xff0c;这给喜欢打私房菜的朋友提供了极高价值的预测结果~当然了&#xff0…

教育政策与智能技术:构建新时代教师队伍

据最新统计&#xff0c;我国目前拥有各级各类教师共计1891.8万人&#xff0c;这一庞大的教师群体不仅支撑起了全球规模最大的教育体系&#xff0c;更成为了推动教育创新与变革的主力军。面对教育数字化的不断发展&#xff0c;育人内容、目标要求、方式方法的全面升级&#xff0…

【测向定位】差频MUSIC算法DOA估计【附MATLAB代码】

​微信公众号&#xff1a;EW Frontier QQ交流群&#xff1a;554073254 摘要 利用多频处理方法&#xff0c;在不产生空间混叠的情况下&#xff0c;估计出高频区域平面波的波达方向。该方法利用了差频&#xff08;DF&#xff09;&#xff0c;即两个高频之间的差。这使得能够在可…

鹏鼎控股社招校招入职SHL综合能力测评:高分攻略及真题题库解析答疑

鹏鼎控股&#xff08;深圳&#xff09;股份有限公司&#xff0c;成立于1999年4月29日&#xff0c;是一家专注于印制电路板&#xff08;PCB&#xff09;的设计、研发、制造与销售的高新技术企业。公司总部位于中国广东省深圳市&#xff0c;并在全球多个地区设有生产基地和服务中…

【软考】数据字典(DD)

目录 1. 说明2. 数据字典的内容2.1 说明2.2 数据流条目2.3 数据存储条目2.4 数据项条目2.5 基本加工条目 3. 数据词典管理4. 加工逻辑的描述4.1 说明4.2 结构化语言4.3 判定表4.3 判定树 5. 例题5.1 例题1 1. 说明 1.数据流图描述了系统的分解&#xff0c;但没有对图中各成分进…

软件自动定时启动器-添加可执行文件软件,设置启动的时间,也可以设置关闭的时间-供大家学习研究参考

点击添加软件&#xff0c;可以添加可执行文件软件&#xff0c;设置启动的时间&#xff0c;也可以设置关闭的时间 注意&#xff0c;时间为00&#xff1a;00&#xff1a;00 等于没设置&#xff0c;这个时间不在设置范围&#xff0c;其他任何时间都可以。 下载地址&#xff1a; h…

【C++ Primer Plus习题】16.9

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: #include <iostream> #include <ctime> #include <v…

驱动---动态模块编译

动态模块编译 ctags 用法 创建文件 ------- ctags -R 一定要在顶层目录下 1&#xff0e; ctags –R * 2. vi –t tag (请把tag替换为您欲查找的变量或函数名) 3&#xff0e; Ctrl ] (跳转到要找的目标) 4&#xff0e; Ctrl T (回跳) 5&#xff0e; set tag/p…

解决使用nvm管理node版本时提示npm下载失败的问题

目录 一、引言 二、解决步骤 1. 访问该网站下载对应版本的npm Release v6.14.18 npm/cli GitHubthe package manager for JavaScript. Contribute to npm/cli development by creating an account on GitHub.https://github.com/npm/cli/releases/tag/v6.14.18 2. 解压到n…

mac使用技巧

mac使用技巧 快捷键 Command-X&#xff1a;剪切所选项并拷贝到剪贴板。Command-C&#xff1a;将所选项拷贝到剪贴板。这同样适用于“访达”中的文件。Command-V&#xff1a;将剪贴板的内容粘贴到当前文稿或应用中。这同样适用于“访达”中的文件。Command-Z&#xff1a;撤销上…

高级算法设计与分析 学习笔记6 B树

B树定义 一个块里面存了1000个数和1001个指针&#xff0c;指针指向的那个块里面的数据大小介于指针旁边的两个数之间 标准定义&#xff1a; B树上的操作 查找B树 创建B树 分割节点 都是选择正中间的那个&#xff0c;以免一直分裂。 插入数字 在插入的路上就会检查节点需不需要…

Ansible——Playbook基本功能???

文章目录 一、Ansible Playbook介绍1、Playbook的简单组成1&#xff09;“play”2&#xff09;“task”3&#xff09;“playbook” 2、Playbook与ad-hoc简单对比区别联系 3、YAML文件语法&#xff1a;---以及多个---&#xff1f;&#xff1f;使用 include 指令 1. 基本结构2. 数…

搜维尔科技:Haption力反馈遥操作解决方案

硬件设备 多种力反馈设备型号&#xff1a; 1.Haption Virtuose 6D&#xff1a;能在 6 个自由度&#xff08;x、y、z 轴 3 个平移和 3 个旋转&#xff09;上提供精确的力反馈&#xff0c;工作空间相当于一条人体手臂的活动范围&#xff0c;最大力度和旋转扭矩分别高达 35N 和 …

干货:分享6款ai论文写作助手,一键生成原创论文(步骤+工具)

写一篇论文是一个复杂的过程&#xff0c;涉及多个步骤&#xff0c;包括选题、研究、撰写、编辑和校对。AI可以在其中的一些步骤中提供帮助&#xff0c;但最终的论文还是需要人类作者的深入思考和创造性输入。以下是六款值得推荐的AI论文写作助手&#xff0c;其中特别推荐千笔-A…

秃姐学AI系列之:目标检测(物体检测) + 边缘框代码实现 | 锚框 + 代码实现

目录 目标检测 边缘框 目标检测数据集 总结 代码实现 定义在两种表示之间进行转换的函数 定义图像中狗和猫的边界框 将边框在图中画出 锚框 Anchor Box IoU——交并比 赋予锚框标号 使用非极大值抑制&#xff08;NMS&#xff09;输出 总结 代码实现 锚框 IoU——交…

高并发内存池(三):CentralCache与PageCache的实现

目录 CentralCache的实现 主体框架 ​Span 页与页号 WIN32、_WIN32、_W64的区别 条件编译 SpanList 为ThreadCache分配内存结点 补充内容1 补充内容2 具体实现 从PageCache申请非空span 补充内容 具体实现 PageCache的实现 主体框架 关于整体加锁的解释 桶锁…

linux第三课(linux中安装nginx与redis及SpringBoot集成redis)

目录 一.nginx引入 二.关于nginx 1.什么是nginx 2.nginx的特点 3.在nginx中安装nginx 三.关于redis 1.背景引入 2.什么是redis 3.redis的特点 4.在linux下的docker中安装redis 四.redis中的数据结构 (1)String(字符串) (2)Hash (3)list(列表) (5)zset(sorted se…

1734. 解码异或后的排列

1. 题目 1734. 解码异或后的排列 2. 解题思路 要搞明白这个题目可以先来看下它的简化版题目&#xff1a;1720. 解码异或后的数组 [!NOTE] 题目&#xff1a; 未知 整数数组 arr 由 n 个非负整数组成。 经编码后变为长度为 n - 1 的另一个整数数组 encoded &#xff0c;其中 e…

ES6标准---【八】【学习ES6看这一篇就够了!!!】

目录 前言 export命令 输出变量 输出函数/类 export中的as别名 export必须一一对应 export接口的响应性 注意 import命令 import命令的语法 import命令里的as别名 import的只读性 import命令具有提升性 import的一些约定 import的静态执行 import的唯一执行性 模…