Qt第三课 ----------布局

devtools/2024/11/14 1:57:21/

作者前言

🎂 ✨✨✨✨✨✨🍧🍧🍧🍧🍧🍧🍧🎂
​🎂 作者介绍: 🎂🎂
🎂 🎉🎉🎉🎉🎉🎉🎉 🎂
🎂作者id:老秦包你会, 🎂
简单介绍:🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂
喜欢学习C语言、C++和python等编程语言,是一位爱分享的博主,有兴趣的小可爱可以来互讨 🎂🎂🎂🎂🎂🎂🎂🎂
🎂个人主页::小小页面🎂
🎂gitee页面:秦大大🎂
🎂🎂🎂🎂🎂🎂🎂🎂
🎂 一个爱分享的小博主 欢迎小可爱们前来借鉴🎂


布局

  • **作者前言**
  • 介绍
  • 垂直布局
  • 水平布局
  • 网格布局
  • 表单布局
  • Spacer
    • SpacerItem添加逻辑

介绍

前面我们写过很多的Qt代码, 我们可以通过代码去布局,
也就是每个控件所在的位置, 都需要计算坐标, 最终通过 setGeometry 或者 move ⽅式摆放过去.这种设定⽅式其实并不⽅便. 尤其是界⾯如果内容⽐较多, 不好计算. ⽽且⼀个窗⼝⼤⼩往往是可以调整的, 按照绝对定位的⽅式, 也⽆法⾃适应窗⼝⼤⼩.
还有就是通过ui文件手动布局,但是这种布局不太好,因为无法明确的分布好位置, 窗口的大小也很难控制,
所以就有以下布局

垂直布局

使⽤ QVBoxLayout 表⽰垂直的布局管理器 layout表示布局
属性如下:
在这里插入图片描述
这个只是一个布局管理器,所以没有信号函数
我们简单的写一个代码

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QVBoxLayout * verticallayout = new QVBoxLayout(this);//这里指定垂直管理器放到this中, 如果设置没有,后面就需要添加//创建三个按钮QPushButton * buttonOne = CreateButton(verticallayout);QPushButton * buttonTwo = CreateButton(verticallayout);QPushButton * buttonTherr = CreateButton(verticallayout);//this->setLayout(verticallayout);//如果布局创建没有指定对象树,需要使用}Widget::~Widget()
{delete ui;
}QPushButton * Widget::CreateButton( QVBoxLayout * verticallayout)
{QPushButton * button = new QPushButton("按");//这里不设置this因为我们要把按钮放到QVBoxLayout里verticallayout->addWidget(button);return button;
}

创建一个有三个按钮的垂直布局, 然后添加到this中
效果如下:
在这里插入图片描述
这个布局可以随着窗口的变化而变化,
需要注意的是: 一个widget窗口只能设置一个布局,
如下情况, 如果碰见一个widget窗口设置多个布局,可能里面是创建多个widget,每个widget添加一个布局,如图:
在这里插入图片描述
在Qt的ui文件里面设置这样,虽然我们看见的是一个widget添加了两个布局,其实不是,而是在在里面先创建了两个widget窗口,然后每个窗口添加一个布局,当我们运行出来进行拉伸窗口,就会发现, 里面的布局不会随窗口的变化而变化, 我们可以去查看对于的代码
如图:
在这里插入图片描述
可以看见里面嵌套了两个widget

水平布局

使⽤ QHBoxLayout 表⽰垂直的布局管理器. H 是 horizontal 的缩写.
水平管理器的属性和垂直管理器的是一样的
在这里插入图片描述
下面我们写一个简单的代码来演示一下

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);
//    CreateLayout(this);}Widget::~Widget()
{delete ui;
}
void Widget::CreateLayout(QWidget * parent)
{//布局创建QHBoxLayout * horizontallayout = new QHBoxLayout();//布局添加控件horizontallayout->addWidget(new QPushButton("按钮"));horizontallayout->addWidget(new QPushButton("按钮"));horizontallayout->addWidget(new QPushButton("按钮"));horizontallayout->addWidget(new QPushButton("按钮"));parent->setLayout(horizontallayout);horizontallayout->addLayout(CreateVLayout());//水平布局里面嵌套垂直布局}QVBoxLayout * Widget::CreateVLayout()
{//布局创建QVBoxLayout * vLayout = new QVBoxLayout();//布局添加控件vLayout->addWidget(new QPushButton("按钮"));vLayout->addWidget(new QPushButton("按钮"));vLayout->addWidget(new QPushButton("按钮"));vLayout->addWidget(new QPushButton("按钮"));return vLayout;
}void Widget::on_pushButton_clicked()
{//添加QString name("窗口");ui->tabWidget->addTab(new QWidget(),name+QString::number(ui->tabWidget->currentIndex()));
}void Widget::on_pushButton_2_clicked()
{//删除当前的窗口if(ui->tabWidget->currentIndex() >=0)ui->tabWidget->removeTab(ui->tabWidget->currentIndex());
}void Widget::on_pushButton_3_clicked()
{CreateLayout(ui->tabWidget->currentWidget());ui->tabWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);}

效果:
在这里插入图片描述
注意:布局里面可以嵌套布局,Layout ⾥⾯可以再嵌套上其他的 layout, 从⽽达到更复杂的布局效果.

网格布局

Qt 中提供了 QGridLayout ⽤来实现⽹格布局的效果. 可以达到 M * N 的这种⽹格的效果
属性如下:
在这里插入图片描述
下面我们写一个简单的:

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);CreateGridlayout(this);}Widget::~Widget()
{delete ui;
}QGridLayout *Widget::CreateGridlayout(QWidget * parent)
{//创建一个表格布局QGridLayout*  grid = new QGridLayout();//创建三个按钮QPushButton *buttonOne = new QPushButton("按钮");QPushButton *buttonTwo = new QPushButton("按钮");QPushButton *buttonThree = new QPushButton("按钮");grid->addWidget(buttonOne, 0,0);grid->addWidget(buttonTwo, 0,1);grid->addWidget(buttonThree, 5,100);//不会间隔很远parent->setLayout(grid);return grid;
}

效果图:

在这里插入图片描述
在代码中, 设置了 grid->addWidget(buttonThree, 5,100),这个代码, 虽然写了很大,但是实际运行出来间隔是不大的因为,每一个按钮都会占据一行或者一列,但是这个值和上⼀个值之间并
没有其他的元素,不会因为设置很大就间隔很多,

除此之外,我们会发现,不管是啥布局,创建出来的控件的大小和间隔都是一样的,如果我们想创建一些大小和间隔不同的控件, 就需要我们去调节拉伸系数(比例)

在此代码的基础上我们添加列拉伸系数看看

grid->setColumnStretch(0,0);grid->setColumnStretch(1,9);//第二列的大小是第一列大小的9倍

效果如下:
在这里插入图片描述
如果倍数为0的话,就是不参与拉伸,大小是固定的了

如果使用行的拉伸系数的话,直接使用会看不见效果的 直接设置 setRowStretch 效果不明显, 因为每个按钮的⾼度是固定的. 需要把按钮的垂直⽅向的 sizePolicy 属性设置为 QSizePolicy::Expanding 尽可能填充满布局管理器, 才能看到效果,
sizepolicy的其中的一个枚举类型,如图:
在这里插入图片描述
使⽤ setSizePolicy 设置按钮的尺⼨策略. 可选的值如下:
• QSizePolicy::Ignored : 忽略控件的尺⼨,不对布局产⽣影响。
• QSizePolicy::Minimum : 控件的最⼩尺⼨为固定值,布局时不会超过该值。
• QSizePolicy::Maximum : 控件的最⼤尺⼨为固定值,布局时不会⼩于该值。
• QSizePolicy::Preferred : 控件的理想尺⼨为固定值,布局时会尽量接近该值。
• QSizePolicy::Expanding : 控件的尺⼨可以根据空间调整,尽可能占据更多空间。
• QSizePolicy::Shrinking : 控件的尺⼨可以根据空间调整,尽可能缩⼩以适应空间。

我们重新写一个新的代码进一步演示

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QGridLayout * grid = CreateGridlayout(this);grid->setColumnStretch(0,1);//如果不设置,就会固定大小grid->setColumnStretch(1,9);//第二列的大小是第一列大小的9倍grid->setRowStretch(0,1);//如果不设置,就会固定大小grid->setRowStretch(1,2);//第二行的大小是第一行大小的2倍}Widget::~Widget()
{delete ui;
}QGridLayout *Widget::CreateGridlayout(QWidget * parent)
{//创建一个表格布局QGridLayout*  grid = new QGridLayout();//创建三个按钮QPushButton *buttonOne = CreateButton();QPushButton *buttonTwo =CreateButton();QPushButton *buttonThree = CreateButton();grid->addWidget(buttonOne, 0,0);grid->addWidget(buttonTwo, 0,1);grid->addWidget(buttonThree, 1,0);//不会间隔很远parent->setLayout(grid);return grid;
}QPushButton *Widget::CreateButton()
{QPushButton *button = new QPushButton("按钮");//给按钮设置在水平和垂直的方向尽可能的伸展button->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);return button;
}

效果图:
在这里插入图片描述

表单布局

使⽤ QFormLayout 创建表单,属于是 QGridLayout 的特殊情况, 专⻔⽤于实现两列表单的布局
这种表单布局多⽤于让⽤⼾填写信息的场景. 左侧列为提⽰, 右侧列为输⼊框
属性如下:

addRow(): 添加一行,通常包含一个标签和一个控件。
*addRow(QString, QWidget)**: 添加一行,使用字符串作为标签。
setLabelAlignment(): 设置标签的对齐方式。
setSpacing(): 设置控件之间的间距。
setMargin(): 设置布局的边缘间距。
写一个简单的代码:

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);this->setLayout(CreateForm());
}Widget::~Widget()
{delete ui;
}QFormLayout *Widget::CreateForm()
{//创建表单QFormLayout* form = new QFormLayout();//创建三个标签和输入框CreateLabel_InputBox_And_Add(form, "账号:","请输入账号");CreateLabel_InputBox_And_Add(form, "密码:","请输入密码");CreateLabel_InputBox_And_Add(form, "邀请码:","请输入邀请码");// 提交按钮QPushButton * button = new QPushButton("提交");form->addRow(button);form->setMargin(300);//边框距离form->setSpacing(50);form->setHorizontalSpacing(10);,水平方向的控件之间的间距return form;}void Widget::CreateLabel_InputBox_And_Add(QFormLayout *form, QString name,QString textValue)
{//创建标签QLabel * label = new QLabel(name);//创建输入框QLineEdit * lineEdit1 = new QLineEdit();lineEdit1->setPlaceholderText(textValue);form->addRow(label, lineEdit1);}

效果如下:
在这里插入图片描述

Spacer

使⽤布局管理器的时候, 可能需要在控件之间, 添加⼀段空⽩. 就可以使⽤ QSpacerItem 来表⽰.
这个在布局中添加这个,不太一样,下面我们演示一下:
属性如下:
在这里插入图片描述

代码如下:

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);CreateLayot<QHBoxLayout>(this);
}Widget::~Widget()
{delete ui;
}template<typename v = QLayout>
v *  Widget::CreateLayot(QWidget * parent)
{//创建布局v* layout = new v();//创建一个间隙QSpacerItem * spacer= new QSpacerItem(200,100);if(typeid (v).name() != typeid (QGridLayout).name()){//这里的空白的间隙添加的位置是看添加的逻辑layout->addWidget(new QPushButton("按钮"));layout->addSpacerItem(spacer);layout->addWidget(new QPushButton("按钮"));}parent->setLayout(layout);}

效果图:
在这里插入图片描述

SpacerItem添加逻辑

如果我们要把QSpacerItem添加到第一个按钮前面, 我们需要把代码添加到前面就行,
如图:
在这里插入图片描述


http://www.ppmy.cn/devtools/133803.html

相关文章

API接口精准获取商品详情信息案例

在当今数字化时代&#xff0c;电子商务平台的蓬勃发展&#xff0c;使得商品信息的获取变得尤为重要。API&#xff08;Application Programming Interface&#xff0c;应用程序编程接口&#xff09;作为连接前端用户界面与后端服务的桥梁&#xff0c;扮演着至关重要的角色。本文…

Python——飞机大战

以下是一个简单的用Python编写的飞机大战游戏的源代码&#xff1a; import pygame import random# 初始化游戏 pygame.init()# 设置游戏窗口的尺寸 screen_width 480 screen_height 640 screen pygame.display.set_mode((screen_width, screen_height))# 设置游戏标题 pyga…

516.最长回文子序列

刷算法题&#xff1a; 第一遍&#xff1a;1.看5分钟&#xff0c;没思路看题解 2.通过题解改进自己的解法&#xff0c;并且要写每行的注释以及自己的思路。 3.思考自己做到了题解的哪一步&#xff0c;下次怎么才能做对(总结方法) 4.整理到自己的自媒体平台。 5.再刷重复的类…

HTTP常见的请求头有哪些?都有什么作用?在 Web 应用中使用这些请求头?

HTTP 请求头&#xff08;Request Headers&#xff09;用于在 HTTP 请求中携带额外的信息&#xff0c;帮助服务器更好地处理请求。以下是一些常见的 HTTP 请求头及其作用&#xff1a; 常见请求头及其作用 1. Accept 作用&#xff1a;告知服务器客户端可以接受的内容类型。示例…

Java设计模式面试题及参考答案

目录 什么是单例模式?它的应用场景是什么?如何保证单例模式线程安全? 什么是工厂方法模式?如何与简单工厂模式进行比较? 抽象工厂模式和工厂方法模式有什么区别?请给出实际应用场景。 什么是建造者模式?它和工厂模式有什么不同? 解释原型模式及其应用。如何通过克隆…

【轻量化】YOLOv8 更换骨干网络之 MobileNetv4 | 模块化加法!非 timm 包!

之前咱们在这个文章中讲了timm包的加法,不少同学反馈要模块化的加法,那么这篇就讲解下模块化的加法,值得注意的是,这样改加载不了mobilebnetv4官方开源的权重了~ 论文地址:https://arxiv.org/pdf/2404.10518 代码地址:https://github.com/tensorflow/models/blob/master…

如何利用AI技术在电商平台中做购物推荐?

数据收集与整合 用户行为数据&#xff1a;收集用户在电商平台上的各种行为数据&#xff0c;包括浏览历史&#xff08;用户浏览了哪些商品页面、停留时间长短等&#xff09;、购买历史&#xff08;购买过的商品类别、品牌、价格等&#xff09;、收藏夹内容、加入购物车但未购买的…

Python数据分析NumPy和pandas(二十七、数据可视化 matplotlib API 入门)

数据可视化或者数据绘图是数据分析中最重要的任务之一&#xff0c;是数据探索过程的一部分&#xff0c;数据可视化可以帮助我们识别异常值、识别出需要的数据转换以及为模型生成提供思考依据。对于Web开发人员&#xff0c;构建基于Web的数据可视化显示也是一种重要的方式。Pyth…