当前位置: 首页 > article >正文

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

作者前言

🎂 ✨✨✨✨✨✨🍧🍧🍧🍧🍧🍧🍧🎂
​🎂 作者介绍: 🎂🎂
🎂 🎉🎉🎉🎉🎉🎉🎉 🎂
🎂作者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.kler.cn/a/393395.html

相关文章:

  • 01 - 初识 Spring
  • MySQL45讲 第三十六讲 为什么临时表可以重名?——阅读总结
  • 论文阅读 - 《Large Language Models Are Zero-Shot Time Series Forecasters》
  • centos制作离线安装包
  • 解线性方程组
  • 服务器上加入SFTP------(小白篇 1)
  • 国内AI工具复现GPTs效果详解
  • vue文本高亮处理
  • 【Git】如何在 Git 项目中引用另一个 Git 项目:子模块与子树合并
  • 学习threejs,导入STL格式的模型
  • 【Linux】ELF可执行程序和动态库加载
  • CSS高级技巧_精灵图_字体图标_CSS三角_vertical-align(图像和文字居中在同一行)_溢出文字省略号显示
  • 随机森林(Random Forest)算法Python代码实现
  • 数据量大Excel卡顿严重?选对报表工具提高10倍效率
  • 同三维T85HU HDMI+USB摄像机多路多机位手机直播采集卡
  • 浅析pytorch中的常见函数和方法
  • 128.WEB渗透测试-信息收集-ARL(19)
  • DDE(深度桌面环境) Qt 6.8 适配说明
  • 嵌入式开发套件(golang版本)
  • 昇思大模型平台打卡体验活动:项目6基于MindSpore通过GPT实现情感分类
  • 力扣662:二叉树的最大宽度
  • Java面向对象编程进阶之包装类
  • Python---re模块(正则表达式)
  • 快递鸟快递查询API接口参数代码
  • 字符设备 - The most important !
  • JavaScript 中实例化生成对象的相关探讨