QT笔记8__布局管理器QBoxLayout、QGridLayout、QFormLayout、QSizePolicy
简介
Qt布局管理器为界面提通过一种强大的自动排列部件的功能,利用布局管理能够合理的利用窗口空间,并在窗口进行缩放调整时,自动调整控件距离和大小来可以保存窗口的美观和有序;
QT中的布局管理器有四种:QBoxLayout、QGridLayout、QFormLayout、QStackedLayout,分别表示基本布局管理器、栅格布局管理器、窗体布局管理器、栈布局管理器。其中基本布局管理器QBoxLayout又分为水平布局管理器QHBoxLayout和垂直布局管理器QVBoxLayout。
以上布局管理器均继承自QLayout,而QLayout继承自QObject和QLayoutItem,继承关系如下图所示:
一、布局管理器的基本使用
1、Qt Designer中的布局;
在采用Qt Designer进行界面设计时,可以直接通过点击Designer界面上相关布局按钮来实现布局管理,简单、方便,易于理解。如图下图所示:
- 按钮‘1’,‘2’,‘3’,采用的是水平布局管理,利用箭头与水平管理器按钮连接;
- 按钮‘4’,‘7’,采用的是垂直布局管理,利用箭头与垂直管理器按钮连接;
- 按钮‘5’,‘6’,‘8’,‘9’,采用的是栅格布局管理,利用箭头与栅格管理器按钮连接;
2、QBoxLayout
- 基本实现效果
QBoxLayout分为水平布局管理器QHBoxLayout和垂直布局管理器QVBoxLayout,直接使用代码来进行布局管理也非常简单。
//QHBoxLayout水平布局管理:
QWidget *myDlg = new QWidget;
myDlg->setWindowTitle(QString::fromLocal8Bit("小码哥的水平布局管理"));
QHBoxLayout* wyHLayout = new QHBoxLayout;
QPushButton* wyButton1 = new QPushButton("1");
QPushButton* wyButton2 = new QPushButton("2");
QPushButton* wyButton3 = new QPushButton("3");
wyHLayout->addWidget(wyButton1);
wyHLayout->addWidget(wyButton2);
wyHLayout->addWidget(wyButton3);
myDlg->setLayout(wyHLayout);
myDlg->show();
水平布局管理实现效果:
//QVBoxLayout垂直布局管理:
QWidget *myDlg = new QWidget;
QVBoxLayout* wyVLayout = new QVBoxLayout;
QPushButton* wyButton1 = new QPushButton("1");
QPushButton* wyButton2 = new QPushButton("2");
QPushButton* wyButton3 = new QPushButton("3");
wyVLayout->addWidget(wyButton1);
wyVLayout->addWidget(wyButton2);
wyVLayout->addWidget(wyButton3);
myDlg->setLayout(wyVLayout);
myDlg->show();
垂直布局管理实现效果:
- 常用函数
在以上代码中QBoxLayou对象调用addWidget()函数添加部件。除此之外还可以利用addItem()和addLayout()添加对应元素,其中addLayout()函数可以实现添加其他的 QLayout类来进行嵌套布局;
QWidget *myDlg = new QWidget;
myDlg->setWindowTitle(QString::fromLocal8Bit("小码哥的嵌套布局管理"));
//第一行
QHBoxLayout* wyHLayout1 = new QHBoxLayout;
QPushButton* wyButton1 = new QPushButton("1");
QPushButton* wyButton2 = new QPushButton("2");
QPushButton* wyButton3 = new QPushButton("3");
wyHLayout1->addWidget(wyButton1);
wyHLayout1->addWidget(wyButton2);
wyHLayout1->addWidget(wyButton3);
//第二行
QHBoxLayout* wyHLayout2 = new QHBoxLayout;
QPushButton* wyButton4 = new QPushButton("4");
QPushButton* wyButton5 = new QPushButton("5");
QPushButton* wyButton6 = new QPushButton("6");
wyHLayout2->addWidget(wyButton4);
wyHLayout2->addWidget(wyButton5);
wyHLayout2->addWidget(wyButton6);
//第三行
QHBoxLayout* wyHLayout3 = new QHBoxLayout;
QPushButton* wyButton7 = new QPushButton("7");
QPushButton* wyButton8 = new QPushButton("8");
QPushButton* wyButton9 = new QPushButton("9");
wyHLayout3->addWidget(wyButton7);
wyHLayout3->addWidget(wyButton8);
wyHLayout3->addWidget(wyButton9);
QVBoxLayout* wyVLayout = new QVBoxLayout;
wyVLayout->addLayout(wyHLayout1);
wyVLayout->addLayout(wyHLayout2);
wyVLayout->addLayout(wyHLayout3);
myDlg->setLayout(wyVLayout);
myDlg->show();
实现效果
- 方向设置
通过利用setDirection(Direction)函数可以对基本布局管理器进行方向设置,方向由枚举Direction来指定:
Direction { LeftToRight, RightToLeft, TopToBottom, BottomToTop,
Down = TopToBottom, Up = BottomToTop };
3、QGridLayout
- 基本实现效果
栅格布局管理器是比基本布局更加灵活的布局管理器,利用该布局管理器可以准确的指定部件所处的行、列位置以及所占的空间大小,基本实现代码如下:
//*********************************************栅格布局管理器
QWidget *myDlg = new QWidget;
myDlg->setWindowTitle(QString::fromLocal8Bit("小码哥的栅格布局管理"));
//
QGridLayout* wyGridLayout = new QGridLayout;
QPushButton* wyButton1 = new QPushButton("1");
QPushButton* wyButton2 = new QPushButton("2");
QPushButton* wyButton3 = new QPushButton("3");
QPushButton* wyButtonZ = new QPushButton("0");
QPushButton* wyButtonP = new QPushButton(".");
wyGridLayout->addWidget(wyButton1, 0, 0);//0行0列;
wyGridLayout->addWidget(wyButton2, 0, 1);//0行1列;
wyGridLayout->addWidget(wyButton3, 0, 2);//0行2列;
wyGridLayout->addWidget(wyButtonZ, 1, 0,1,2);//1行0列,占1行,占2列;
wyGridLayout->addWidget(wyButtonP, 1, 2);//1行2列;
myDlg->setLayout(wyGridLayout);
myDlg->show();
实现效果:
- 常用函数
添加部件到部件管理其中主要采用以下两类函数:
addWidget(QWidget *, int row, int column, Qt::Alignment = 0)
addWidget(QWidget *, int row, int column, int rowSpan, int columnSpan, Qt::Alignment = 0)
addLayout(QLayout *, int row, int column, Qt::Alignment = 0)
addLayout(QLayout *, int row, int column, int rowSpan, int columnSpan, Qt::Alignment = 0)
第一个参数为对应部件的指针;
row和column为部件所处的位置;
owSpan和ColumnSpan则为控件扩展的倍数,当取值为-1时则控件将扩展到底部和最右边缘;
Qt::Alignment为对齐方式;
4、QFormLayout
- 基本实现效果
窗体布局可以用来实现一个标签+部件的快速布局操作;具体代码实现如下:
////*********************************************窗体布局管理器
QWidget *myDlg = new QWidget;
myDlg->setWindowTitle(QString::fromLocal8Bit("小码哥的窗体布局管理"));
QPushButton *wyButton1 = new QPushButton(QString::fromLocal8Bit("姓名:"));
QLineEdit *wylineEdit1 = new QLineEdit();
QPushButton *wyButton2 = new QPushButton(QString::fromLocal8Bit("年龄:"));
QLineEdit *wylineEdit2 = new QLineEdit();
QPushButton *wyButton3 = new QPushButton(QString::fromLocal8Bit("性别:"));
QLineEdit *wylineEdit3 = new QLineEdit();
QFormLayout *wyFlayout = new QFormLayout;
wyFlayout->addRow(wyButton1, wylineEdit1);
wyFlayout->addRow(wyButton2, wylineEdit2);
wyFlayout->addRow(wyButton3, wylineEdit3);
myDlg->setLayout(wyFlayout);
myDlg->show();
实现效果:
- 常用函数
窗体布局添加元素,主要采用addRow()函数进行,函数主要有以下几种重载方式,可以实现对布局和Qlayout的布局;
void addRow(QWidget *label, QWidget *field);
void addRow(QWidget *label, QLayout *field);
void addRow(const QString &labelText, QWidget *field);
void addRow(const QString &labelText, QLayout *field);
void addRow(QWidget *widget);
void addRow(QLayout *layout);
二、布局的优化
为了使窗口的的布局更加灵活多样,在界面布局中除了以上所述添加控件的基本函数之外,布局管理器还提供了一些函数供用户进行布局的细节调整,例如间隔、比例、尺寸限制等;另外界面设计中也经常通过调节控件的sizePolicy属性来优化界面布局。
1、间距、空间比例、尺寸限制
不同的布局管理器的布局管理器提供的相关控制函数略有不同,QGridLayout中常用空间控制相关函数如下所示,其他布局管理器可按照相关功能查找对应函数;
- 间距设置
void setHorizontalSpacing(int spacing);//设置所有控件水平间隔宽度;
void setVerticalSpacing(int spacing);//设置所有控件垂直间隔高度;
void setSpacing(int spacing);//设置所有控件间隔宽度;
- 比例设置
void setRowStretch(int row, int stretch);//设置指定行之间的比例;
void setColumnStretch(int column, int stretch);//设置指定列之间的比例;
- 尺寸限制
void setRowMinimumHeight(int row, int minSize);//设置某行,最小高度
void setColumnMinimumWidth(int column, int minSize);//设置某行,最小框度
2、控件的QSizePolicy属性
布局管理器中往往包含多个控件,我们可以通过设置控件的QSizePolicy属性来调节控件对空间的争夺能力,来实现不同的控件布局和缩放效果,控件本身的尺寸属性主要有两个:sizeHint 和sizePolicy;
- 其中sizeHint为Qt提供给控件的默认尺寸,通过sizeHint()函数可以返回该尺寸;
- sizePolicy则决定了控件的尺寸行为,由枚举QSizePolicy::Policy来指定,利用函数setSizePolicy()进行行方向和列方向的Policy属性设置;
QSizePolicy::Fixed widget 的实际尺寸只参考 sizeHint() 的返回值,不能伸展(grow)和收缩(shrink)
QSizePolicy::Minimum 可以伸展和收缩,不过sizeHint() 的返回值规定了 widget 能缩小到的最小尺寸
QSizePolicy::Maximum 可以伸展和收缩,不过sizeHint() 的返回值规定了 widget 能伸展到的最大尺寸
QSizePolicy::Preferred 可以伸展和收缩,但没有优势去获取更大的额外空间使自己的尺寸比 sizeHint() 的返回值更大
QSizePolicy::Expanding 可以伸展和收缩,它会尽可能多地去获取额外的空间,也就是比 Preferred 更具优势
QSizePolicy::MinimumExpanding 可以伸展和收缩,不过sizeHint() 的返回值规定了 widget 能缩小到的最小尺寸,同时它比 Preferred 更具优势去获取额外空间
由上可知,控件在没限制大小的情况下,空间争夺能力MinimumExpanding>Expanding >Preferred ;