盒子布局
QBoxLayout可以在水平方向或垂直方向上排列控件,分别派生了QHBoxLayout、QVBoxLayout子类。
- QHBoxLayout:水平布局,在水平方向上排列控件,即:左右排列。
- QVBoxLayout:垂直布局,在垂直方向上排列控件,即:上下排列。
水平布局、垂直布局除了构造时的方向(LeftToRight、TopToBottom)不同外,其它均相同。
水平布局
auto tiplabel = new QLabel("用户名");
auto lindEdet = new QLineEdit;
auto hlayout = new QHBoxLayout;
hlayout->addWidget(tiplabel);
hlayout->addWidget(lindEdet);
setLayout(hlayout);
垂直布局
auto tiplabel = new QLabel("用户名");
auto lindEdet = new QLineEdit;
auto vlayout = new QVBoxLayout;
vlayout->addWidget(tiplabel);
vlayout->addWidget(lindEdet);
setLayout(vlayout);
嵌套布局
水平布局会把所有的控件都显示在一行上,垂直布局会把所有控件显示在一列上,如果要显示多行(比如登录界面),那么就要通过水平布局和垂直布局之间的嵌套实现。
auto tiplabel = new QLabel("用户名");
auto lindEdet = new QLineEdit;
auto hlayout = new QHBoxLayout
hlayout->addWidget(tiplabel);
hlayout->addWidget(lindEdet);
auto tiplabel1 = new QLabel("密码");
auto lindEdet1 = new QLineEdit;
auto hlayout1 = new QHBoxLayout;
hlayout1->addWidget(tiplabel1);
hlayout1->addWidget(lindEdet1)
auto vlayout = new QVBoxLayout;
vlayout->addLayout(hlayout);
vlayout->addLayout(hlayout1)
setLayout(vlayout);
一行就是一个水平布局,然后将水平布局嵌入在垂直布局中。
精细化操作
先来一组按钮
QPushButton* btn1 = new QPushButton("One");
QPushButton* btn2 = neQPushButton("Two");
QPushButton* btn3 = neQPushButton("Three");
QPushButton* btn4 = neQPushButton("Four");
QPushButton* btn5 = neQPushButton("Five")
QHBoxLayout* hlayout = neQHBoxLayout;
hlayout->addWidget(btn1);
hlayout->addWidget(btn2);
hlayout->addWidget(btn3);
hlayout->addWidget(btn4);
hlayout->addWidget(btn5)
this->setLayout(hlayout);
这一排按钮和窗口之间有边距,按钮和按钮之间也存在间隙,这些边距和间隙是可调节的。
调节边距
void QLayout::setContentsMargins(int left, int top, int right, int bottom)
hlayout->setContentsMargins(0, 0, 0, 0);
调节边界
void setSpacing(int spacing)
hlayout->setSpacing(0);
拉伸窗口,会发现窗口上的按钮会随着窗口的拉伸而变大/变小,如果窗口变大很大,那么这些按钮是不是就会很难看。
如果在拉伸的过程中按钮的变化是这样的是不是就很好了。要实现这个效果很简单,只要添加拉伸空间就可以了。
QHBoxLayout* hlayout = new QHBoxLayout;
hlayout->addStretch(); //添加拉伸空间
hlayout->addWidget(btn1);
...
在第一个控件之前添加伸缩,这样所有的控件就会居右显示。
在最后一个控件之后添加伸缩,这样所有的控件就会居左显示。
在第一个控件之前,最后一个控件之后添加伸缩,这样所有的控件就会居中显示。
这个时候拉伸窗口,你会发现窗口上的各个按钮的变化是相同的,如果你想让某些按钮的变化有些不同可以通过设置拉伸系数来实现。
设置拉伸系数
bool setStretchFactor(QWidget *widget, int stretch)
bool setStretchFactor(QLayout *layout, int stretch)
hlayout->setStretchFactor(btn2,1);
hlayout->setStretchFactor(btn3,2);
网格布局
栅格布局将位于其中的窗口部件放入一个网状的栅格之中。QGridLayout将提供给它的空间划分成的行和列,并把每个窗口部件插入并管理到正确的单元格。 栅格布局会计算位于其中的空间,然后将它们合理的划分成若干个行(row)和列(column),并把每个由它管理的窗口部件放置在合适的单元之中。
对于这个页面通过网格布局进行创建,可以划分成4行4列。一个控件并不是只能占一个单元格,而是可以跨行和跨列的。
void glayout(){
QLabel* imageLabel = new QLabel;
QLineEdit* userNamaeEdit = new QLineEdit;
QLineEdit* passwdEdit = new QLineEdit;
QCheckBox* rememberCheckBox new QCheckBox;
QCheckBox* autoLoginCheckBox new QCheckBox;
QPushButton* registerBtn = new QPushButton;
QPushButton* forgetBtn = new QPushButton;
QPushButton* loginBtn = new QPushButton;
imageLabel->setFixedSize(90,90);
imageLabel->setPixmap(QPixm(":/Resource/zay. png"));
imageLabel->setScaledConten(true)
userNamaeEdit->setPlaceholderxt("QQ号码/手机/ 邮箱");
passwdEdit->setPlaceholderText("密码");
rememberCheckBox->setText("密码"); autoLoginCheckBox->setText(动登录");
registerBtn->setText("注册");
forgetBtn->setText("找回密码");
loginBtn->setText("登录")
auto glayout = new QGridLayo(this);
glayout->addWidget(imageLabel0, 0, 3, 1);
glayout->addWidg(userNamaeEdit, 0, 1, 1, 2);
glayout->addWidget(passwdEdit1, 1, 1, 2);
glayout->addWidg(rememberCheckBox, 2, 1, 1, 1);
glayout->addWidg(autoLoginCheckBox, 2, 2, 1,1);
glayout->addWidget(loginBtn3, 1, 1, 2);
glayout->addWidg(registerBtn, 0, 3, 1, 1);
glayout->addWidget(forgetBtn1, 3, 1, 1);
}
表单布局
QFormLayout类管理输入小部件的表单及其关联的标签 以两列形式布置其子项,左列由标签组成,右列由“字段”小部件(行编辑器、旋转框等)组成。表达布局的基本单位是行,通常使用的是addRow()函数。
void addRow(QWidget* label,QWidget* field)
void addRow(QWidget* label,QLayout* field)
使用给定的label和field在此表单布局的底部添加新行
void addRow(const QString &labelText, QWidget* field)
void addRow(const QString &labelText, QLayout* field)
这个重载会在后台自动创建一个以labelText作为文本的QLabel。 field被设置为新的QLabel的伙伴
void addRow(QWidget widget)
void addRow(QLayout layout)
之前用盒子布局中的嵌套结构,制作“用户名密码输入界面,两行文本编辑框是没有对齐的,而如果采用表单布局就不会这样。
使用表单布局实现下面这个界面
void flayout(){
auto usernameEdit = new QLineEdit;
auto passwordLab = new QLabel("密 码");
auto passwrodEdit = neQLineEdit;
auto mobileEdit = neQLineEdit;
auto emailEdit = new QLineEdit
auto manChx = new QCheckBox("男");
auto womanChx = new QCheckBox("女");
flayout->addRow("*用户名", usernameEdit);
flayout->addRow(new QLabel("中文、英文、特殊字 符"));
flayout->addRow("*密码", passwrodEdit);
flayout->addRow("*手机号码", mobileEdit);
flayout->addRow("电子邮箱", emailEdit);
auto hlayout = new QHBoxLayout;
hlayout->addWidget(manChx);
hlayout->addWidget(womanChx);
hlayout->addStretch();
flayout->addRow("性别", hlayout);
}
目前的效果是这样
要想实现显示红色的*以及将字符串 "中文、英文、特殊字符"变小变灰,那么就要使用HTML的标签,对于显示在QLabel上的文字,是可以使用一些HTML标签的
void flayout(){
auto usernameEdit = new QLineEdit;
auto passwordLab = new QLabel("密 码");
auto passwrodEdit = neQLineEdit;
auto mobileEdit = neQLineEdit;
auto emailEdit = new QLineEdit
auto manChx = new QCheckBox("男");
auto womanChx = new QCheckBox("女");
flayout->addRow("<font color=red size=4>*</ font>用户名", usernameEdit);
flayout->addRow(new QLabel("<font color=gray size=2>中文、英文、特殊字符</ font>"));
flayout->addRow("<font color=red size=4>*</ font>密码", passwrodEdit);
flayout->addRow("<font color=red size=4>*</ font>手机号码", mobileEdit);
flayout->addRow("电子邮箱", emailEdit);
auto hlayout = new QHBoxLayout;
hlayout->addWidget(manChx);
hlayout->addWidget(womanChx);
hlayout->addStretch();
flayout->addRow("性别", hlayout);
}
堆栈布局
QStackedLayout 用于管理多个子窗口或页面的堆叠显示。它允许你在一个固定区域内显示多个子窗口,但每次只显示其中一个子窗口,其他子窗口被堆叠在后面。
这里通过堆栈布局管理上文中的网格布局和表单布局,实现一个页面切换的效果。
static QWidget* CreatePage(int id)
{
if (id == 0)
{
QWidget* page = new QWidget;
gridlayout(page);
return page;
}
else if (id == 1)
{
QWidget* page = new QWidget;
formlayout(page);
return page;
}
return nullptr;
}
这里稍微修改了一下girdlayout函数和formlayout函数
girdlayout(QWidget*page)
原来这里填的是this,现在改为page就可以了
auto glayout = new QGridLayout(page);
formlayout(QWidget*page)
原来这里填的是this,现在改为page就可以了
auto flayout = new QFormLayout(page);
void slayout() {
auto btnGroup = new QButtonGro(this);
btnGroup->addButton(new QPushButt("page1"), 0); //0
btnGroup->addButton(new QPushButt("page2"), 1); //1
auto hlayout = new QHBoxLayout;
hlayout->addWidget(btnGroup->butt(0));
hlayout->addWidget(btnGroup->butt(1));
hlayout->addStretch();
//用来管理多个页面的
auto slayout = new QStackedLayout;
slayout->addWidget(CreatePa(0)); //0
slayout->addWidget(CreatePa(1)); //1
auto vlayout = new QVBoxLayout;
vlayout->addLayout(hlayout);
vlayout->addLayout(slayout);
setLayout(vlayout);
//切换页面
qDebug() << slayout->count();
connect(btnGroup,QButtonGroup::idClicked, [=](int id)
{
slayout->setCurrentIndex(id);
});
}