一、布局管理器
1.1、布局管理器的作用
布局管理器是摆放控件的辅助工具,主要解决组件的位置和大小无法自适应父窗口变化的问题,主要功能如下:
- 自动调整控件的位置,包括控件之间的间距、对齐等
- 当用户调整窗口大小时,位于布局管理器内的控件也会随之调整大小,从而保持整个界面的美观
借助布局管理器,无需再逐个调整控件的位置和大小,可以将更多的精力放在软件功能的实现上。
1.2、布局管理器类继承结构图
Qt 共提供了 5 种布局管理器,每种布局管理器对应一个类,分别是 QVBoxLayout(垂直布局)、QHBoxLayout(水平布局)、QGridLayout(网格布局)、QFormLayout(表单布局)和 QStackedLayout(分组布局),继承关系如下图:
二、使用布局管理器
2.1、QVBoxLayout(垂直布局)
将所有控件从上到下(或者从下到上)依次摆放,例如:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//创建主窗口
QWidget widget;
//设置窗口标题
widget.setWindowTitle("QVBoxLayout");
//设置窗口大小
widget.resize(500, 250);
//创建垂直布局管理器
QVBoxLayout *layout = new QVBoxLayout;
//设置布局管理器中所有控件从下往上依次排列
layout->setDirection(QBoxLayout::BottomToTop);
//连续创建 3 个文本框,并设置它们的背景和字体大小
QLabel lab1("Label1");
lab1.setStyleSheet("QLabel{background:#dddddd;font:20px;}");
lab1.setAlignment(Qt::AlignCenter);
QLabel lab2("Label2");
lab2.setStyleSheet("QLabel{background:#cccccc;font:20px;}");
lab2.setAlignment(Qt::AlignCenter);
QLabel lab3("Label3");
lab3.setStyleSheet("QLabel{background:#ffffff;font:20px;}");
lab3.setAlignment(Qt::AlignCenter);
//组件的伸缩系数比是 1:1:1
layout->addWidget(&lab3, 1);
layout->addWidget(&lab2, 1);
layout->addWidget(&lab1, 1);
//将布局管理器添加到widget窗口中
widget.setLayout(layout);
widget.show();
return a.exec();
}
2.2、QHBoxLayout(水平布局)
水平布局指的是将所有控件从左到右(或者从右到左)依次摆放,例如:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//创建主窗口
QWidget widget;
//设置窗口标题
widget.setWindowTitle("QHBoxLayout");
//设置窗口大小
widget.resize(500, 250);
//创建水平布局管理器
QHBoxLayout *layout = new QHBoxLayout;
//设置布局管理器中所有控件的布局方向为从右往左依次排列
layout->setDirection(QBoxLayout::RightToLeft);
//连续创建 3 个文本框,并设置它们的背景和字体大小
QLabel lab1("Label1");
lab1.setStyleSheet("QLabel{background:#dddddd;font:20px;}");
lab1.setAlignment(Qt::AlignCenter);
QLabel lab2("Label2");
lab2.setStyleSheet("QLabel{background:#cccccc;font:20px;}");
lab2.setAlignment(Qt::AlignCenter);
QLabel lab3("Label3");
lab3.setStyleSheet("QLabel{background:#ffffff;font:20px;}");
lab3.setAlignment(Qt::AlignCenter);
//组件的伸缩系数比是 1:1:1
layout->addWidget(&lab3, 1);
layout->addWidget(&lab2, 1);
layout->addWidget(&lab1, 1);
//将布局管理器添加到 widget 窗口中
widget.setLayout(layout);
widget.show();
return a.exec();
}
2.3、QGridLayout(网格布局)
网格布局又称格栅布局或者表格布局,指的是将一些控件按照行和列排列在窗口上,例如:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//创建主窗口
QWidget widget;
//设置窗口标题
widget.setWindowTitle("QGridLayout");
//设置窗口大小
widget.resize(500, 250);
//创建网格布局管理器
QGridLayout *layout = new QGridLayout;
//连续创建 3 个文本框,并设置它们的背景和字体大小
QLabel lab1("Label1");
lab1.setStyleSheet("QLabel{background:#dddddd;font:20px;}");
lab1.setAlignment(Qt::AlignCenter);
QLabel lab2("Label2");
lab2.setStyleSheet("QLabel{background:#cccccc;font:20px;}");
lab2.setAlignment(Qt::AlignCenter);
QLabel lab3("Label3");
lab3.setStyleSheet("QLabel{background:#ffffff;font:20px;}");
lab3.setAlignment(Qt::AlignCenter);
QLabel lab4("Label4");
lab4.setStyleSheet("QLabel{background:#aaaaaa;font:20px;}");
lab4.setAlignment(Qt::AlignCenter);
QLabel lab5("Label5");
lab5.setStyleSheet("QLabel{background:#bbbbbb;font:20px;}");
lab5.setAlignment(Qt::AlignCenter);
//组件添加到网格布局管理器
layout->addWidget(&lab1, 0, 0);
layout->addWidget(&lab2, 0, 1);
layout->addWidget(&lab3, 1, 0, 1, 2);
layout->addWidget(&lab4, 2, 0);
layout->addWidget(&lab5, 2, 1);
//将布局管理器添加到 widget 窗口中
widget.setLayout(layout);
widget.show();
return a.exec();
}
2.4、QFormLayout(表单布局)
Qt 提供了很多种输入框控件,包括 QLineEdit 单行输入框、QTextEdit 多行输入框等。通常情况下,每个输入框的旁边都会附带一些文字(又称标签),用来提示用户需要输入的信息。QFormLayout 可以容纳很多个输入框以及对应的标签,并将它们从上到下依次排列在界面上,如下:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//创建主窗口
QWidget widget;
//设置窗口大小
widget.resize(500, 250);
//设置窗口标题
widget.setWindowTitle("QFormLayout");
//创建表单布局管理器
QFormLayout* layout = new QFormLayout();
//设置表单中的标签都位于控件的上方
layout->setRowWrapPolicy(QFormLayout::WrapAllRows);
//添加 3 行输入框和标签
layout->addRow("Name:", new QLineEdit());
layout->addRow("Email:", new QLineEdit());
layout->addRow("Adress:", new QLineEdit());
//设置行间距和列间距为 10
layout->setSpacing(10);
//将 layout 表单添加到 widget 窗口中
widget.setLayout(layout);
widget.show();
return a.exec();
}
2.5、QStackedLayout(分组局管理器)
QStackedLayout布局管理器可以容纳多个控件或者窗口,但每次只显示其中的一个,如下:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//创建主窗口
QWidget widget;
//设置窗口标题
widget.setWindowTitle("QStackedLayout");
//设置窗口大小
widget.resize(500, 250);
//创建一个列表
QListWidget *listWidget = new QListWidget(&widget);
listWidget->setMinimumWidth(150);
listWidget->setFont(QFont("宋体", 14));
listWidget->addItem("QPushButton");
listWidget->addItem("QLabel");
listWidget->addItem("QLineEdit");
//新建 3 个窗口,分别放置文本框、按钮和单行输入框
QWidget widget1;
widget1.setMinimumSize(200, 200);
QPushButton but1("PushButton", &widget1);
QWidget widget2;
widget2.setMinimumSize(200, 200);
QLabel lab1("This is a Label", &widget2);
QWidget widget3;
widget3.setMinimumSize(200, 200);
QLineEdit edit("This is a QLineEdit", &widget3);
//创建一个分组布局,将 3 个窗口添加到分组控件中
QStackedLayout *stackedLayout = new QStackedLayout;
stackedLayout->addWidget(&widget1);
stackedLayout->addWidget(&widget2);
stackedLayout->addWidget(&widget3);
//向主窗口中添加一个水平布局控件
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(listWidget, 1);
layout->addLayout(stackedLayout, 4);
//将 layout 水平布局控件添加到 widget 窗口中
widget.setLayout(layout);
widget.show();
//连接信号和槽,实现当点击列表中的某一项,切换分组布局管理器显示的控件
QObject::connect(listWidget, &QListWidget::currentRowChanged, stackedLayout, &QStackedLayout::setCurrentIndex);
return a.exec();
}