Qt布局管理器为界面提通过一种强大的自动排列部件的功能,利用布局管理能够合理的利用窗口空间,并在窗口进行缩放调整时,自动调整控件距离和大小来可以保存窗口的美观和有序;
QT中的布局管理器有四种:QBoxLayout、QGridLayout、QFormLayout、QStackedLayout,分别表示基本布局管理器、栅格布局管理器、窗体布局管理器、栈布局管理器。其中基本布局管理器QBoxLayout又分为水平布局管理器QHBoxLayout和垂直布局管理器QVBoxLayout。
以上布局管理器均继承自QLayout,而QLayout继承自QObject和QLayoutItem,继承关系如下图所示:
在采用Qt Designer进行界面设计时,可以直接通过点击Designer界面上相关布局按钮来实现布局管理,简单、方便,易于理解。如图下图所示:
//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();
垂直布局管理实现效果:
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();
实现效果
Direction { LeftToRight, RightToLeft, TopToBottom, BottomToTop,
Down = TopToBottom, Up = BottomToTop };
//*********************************************栅格布局管理器
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为对齐方式;
////*********************************************窗体布局管理器
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();
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属性来优化界面布局。
不同的布局管理器的布局管理器提供的相关控制函数略有不同,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);//设置某行,最小框度
布局管理器中往往包含多个控件,我们可以通过设置控件的QSizePolicy属性来调节控件对空间的争夺能力,来实现不同的控件布局和缩放效果,控件本身的尺寸属性主要有两个:sizeHint 和sizePolicy;
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 ;