作者前言
🎂 ✨✨✨✨✨✨🍧🍧🍧🍧🍧🍧🍧🎂
🎂 作者介绍: 🎂🎂
🎂 🎉🎉🎉🎉🎉🎉🎉 🎂
🎂作者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添加到第一个按钮前面, 我们需要把代码添加到前面就行,
如图: