目录
1. 五大布局
1.1 QVBoxLayout垂直布局
1.2 QHBoxLayout水平布局
1.3 QGridLayout网格布局
1.4 QFormLayout表单布局
1.5 QStackedLayout分组布局
1.6 五大布局综合应用
2. 分割窗口
3. 滚动区域
4. 停靠区域
1. 五大布局
1.1 QVBoxLayout垂直布局
#include <QApplication>
#include <QWidget>
#include <QLabel>
#include <QVBoxLayout>int main(int argc, char *argv[])
{QApplication a(argc, argv);//MainWindow w;//w.show();//创建主窗口QWidget widget;widget.setWindowTitle("QVBoxLayout垂直布局");//创建垂直布局管理器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);//将 3 个文本框和 2 个空白行添加到管理器中,它们的伸缩系数比是 2:1:2:3:3layout->addStretch(2);layout->addWidget(&lab1,1);layout->addWidget(&lab2,2);layout->addWidget(&lab3,3);layout->addStretch(3);//将布局管理器添加到 widget 窗口中widget.setLayout(layout);widget.show();return a.exec();
}
1.2 QHBoxLayout水平布局
#include <QApplication>
#include <QWidget>
#include <QLabel>
#include <QHBoxLayout>
int main(int argc, char *argv[])
{QApplication a(argc, argv);//创建主窗口QWidget widget;widget.setWindowTitle("QHBoxLayout水平布局");//创建水平布局管理器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);//将 3 个文本框和 2 个空白列添加到管理器中,它们的拉伸系数比是 2:1:2:3:3layout->addStretch(2);layout->addWidget(&lab1,1);layout->addWidget(&lab2,2);layout->addWidget(&lab3,3);layout->addStretch(3);//将布局管理器添加到 widget 窗口中widget.setLayout(layout);widget.show();return a.exec();
}
1.3 QGridLayout网格布局
#include <QApplication>
#include <QWidget>
#include <QLabel>
#include <QGridLayout>
#include <QPushButton>int main(int argc, char *argv[])
{QApplication a(argc, argv);//创建主窗口QWidget widget;widget.setWindowTitle("QGridLayout网格布局");//创建 4 个按钮和 1 个文本框QPushButton *but1 = new QPushButton("but1");QPushButton *but2 = new QPushButton("but2");QLabel *lab3 = new QLabel("lab");lab3->setStyleSheet("QLabel{background:#dddddd;font:20px;}");lab3->setAlignment(Qt::AlignCenter);QPushButton *but3 = new QPushButton("but3");QPushButton *but4 = new QPushButton("but4");//创建网格布局控件QGridLayout *layout = new QGridLayout;//向 layout 中添加控件,并指定各个控件的位置layout->addWidget(but1, 0, 0);layout->addWidget(but2, 0, 2);layout->addWidget(lab3, 1, 0, 3, 3); // 从第1行第0列开始占据3行3列layout->addWidget(but3, 4, 0);layout->addWidget(but4, 4, 2);//将 layout 添加到 widget 窗口中widget.setLayout(layout);widget.show();return a.exec();
}
1.4 QFormLayout表单布局
#include <QApplication>
#include <QWidget>
#include <QLineEdit>
#include <QFormLayout>
int main(int argc, char *argv[])
{QApplication a(argc, argv);//创建主窗口QWidget widget;widget.setWindowTitle("QFormLayout表单布局");//创建 4 个按钮和 1 个文本框QFormLayout* layout = new QFormLayout();//设置表单中的标签都位于控件的上方//layout->setRowWrapPolicy(QFormLayout::WrapAllRows);//添加 3 行输入框和标签layout->addRow("Name:", new QLineEdit());layout->addRow("Email:", new QLineEdit());layout->addRow("Adress:", new QLineEdit());//设置行间距和列间距为 10layout->setSpacing(10);//将 layout 表单添加到 widget 窗口中widget.setLayout(layout);widget.show();return a.exec();
}
1.5 QStackedLayout分组布局
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QLabel>
#include <QLineEdit>
#include <QStackedLayout>
#include <QListWidget>
#include <QHBoxLayout>int main(int argc, char *argv[])
{QApplication a(argc, argv);//创建主窗口QWidget widget;widget.setWindowTitle("QStackedLayout分组布局");widget.resize(600,400);//向主窗口中添加一个水平布局控件QHBoxLayout *layout=new QHBoxLayout;//创建一个列表QListWidget listWidget(&widget);listWidget.setMinimumWidth(150);listWidget.setFont(QFont("宋体", 14));listWidget.addItem("QPushButton");listWidget.addItem("QLabel");listWidget.addItem("QLineEdit");//新建 3 个窗口,分别放置文本框、按钮和单行输入框QWidget widget1;widget1.setMinimumSize(400,400);QPushButton but1("这是一个按钮", &widget1);QWidget widget2;widget2.setMinimumSize(400, 400);QLabel lab1("这是一个文本框", &widget2);QWidget widget3;widget3.setMinimumSize(400,400);QLineEdit edit("这是一个单行输入框", &widget3);//创建一个分组布局,将 3 个窗口添加到分组控件中QStackedLayout *stackedLayout = new QStackedLayout;stackedLayout->addWidget(&widget1);stackedLayout->addWidget(&widget2);stackedLayout->addWidget(&widget3);//layout 第一列添加 QListWidget 控件,第二列添加分组布局控件,设置它们的伸缩系数比为 1:4layout->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();
}
1.6 五大布局综合应用
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QWidget>
#include <QMainWindow>
#include <QPushButton> // 用于创建按钮的类
#include <QHBoxLayout> // 用于水平布局的类
#include <QTextEdit> // 用于创建文本框的类
#include <QGridLayout> // 用于栅格布局的类
#include <QLineEdit> // 用于创建行文本框的类
#include <QFormLayout> // 用于表单布局的类
#include <QStackedLayout> // 用于分页布局的类
#include <QComboBox> // 用于下拉框的类namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = 0);~MainWindow();private:Ui::MainWindow *ui;private:QWidget *m_widget;private://演示表单布局QLineEdit *nameLineEdit; // 声明 name 文本框QLineEdit *emailLineEdit; // 声明 email 文本框//演示水平布局QPushButton *button1; // 声明按钮1QPushButton *button2; // 声明按钮2QPushButton *button3; // 声明按钮3QPushButton *button4; // 声明按钮4QPushButton *button5; // 声明按钮5// 演示垂直布局QPushButton *button6; // 声明按钮6QPushButton *button7; // 声明按钮7QPushButton *button8; // 声明按钮8QPushButton *button9; // 声明按钮9QPushButton *button10; // 声明按钮10// 演示网格布局QPushButton *button11; // 声明按钮11QPushButton *button12; // 声明按钮12QTextEdit *gridTextEdit; // 声明文本框// 演示分组布局QPushButton *button13; // 声明按钮13QPushButton *button14; // 声明按钮14QPushButton *button15; // 声明按钮15QPushButton *button16; // 声明按钮16QPushButton *button17; // 声明按钮17QPushButton *button18; // 声明按钮18
};#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"/*
//比较常用的布局微调整接口
QBoxLayout::setSpacing(int spacing); 设置组件之间的间隔,
QBoxLayout::addStretch(int stretch = 0); 设置一个占位空间,
QLayout::setContentsMargins(int left, int top, int right, int bottom); 设置布局管理器到边界的距离。
*/MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);// 设置后页面大小不可调整,一直处于系统推荐大小的状态//this->setFixedSize(sizeHint());// 首先创建一个QWidget并设置给QMainWindow,否则布局看不见m_widget = new QWidget(this);this->setCentralWidget(m_widget);// 演示布局管理器到边界的距离 左 上 右 下m_widget->setContentsMargins(50, 100, 50, 100);// 设置固定大小/*this->setFixedHeight(400);this->setFixedWidth(600);*/// 创建按钮1button1 = new QPushButton("One");// 创建按钮2button2 = new QPushButton("Two");// 创建按钮3button3 = new QPushButton("Three");// 创建按钮4button4 = new QPushButton("Four");// 创建按钮5button5 = new QPushButton("Five");// [1]创建水平页面布局管理对象QHBoxLayout *hlayout = new QHBoxLayout;// 向水平布局增加 按钮1hlayout->addWidget(button1);// 向水平布局增加 按钮2hlayout->addWidget(button2);// 向水平布局增加 按钮3hlayout->addWidget(button3);// 向水平布局增加 按钮4hlayout->addWidget(button4);// 向水平布局增加 按钮5hlayout->addWidget(button5);// 设置水平页面布局是窗口布局//m_widget->setLayout(hlayout);// 演示水平布局之间增加间隔hlayout->setSpacing(200);// 创建按钮6button6 = new QPushButton("Six");// 创建按钮7button7 = new QPushButton("Seven");// 创建按钮8button8 = new QPushButton("Eight");// 创建按钮9button9 = new QPushButton("Nine");// 创建按钮10button10 = new QPushButton("Ten");// [2]创建垂直页面布局管理对象QVBoxLayout *vlayout = new QVBoxLayout;// 向水平布局增加 按钮6vlayout->addWidget(button6);// 向水平布局增加 按钮7vlayout->addWidget(button7);// 演示在按钮之间增加一个占位(弹簧)vlayout->addStretch(1);// 向水平布局增加 按钮8vlayout->addWidget(button8);// 向水平布局增加 按钮9vlayout->addWidget(button9);// 向水平布局增加 按钮10vlayout->addWidget(button10);// 创建按钮11button11 = new QPushButton("Eleven");// 创建按钮12button12 = new QPushButton("Twelve");// 创建文本框gridTextEdit = new QTextEdit();// [4]创建栅格页面布局管理对象QGridLayout *gridLayout = new QGridLayout;gridLayout->addWidget(button11,0,0,1,1);gridLayout->addWidget(button12,0,1,1,1);gridLayout->addWidget(gridTextEdit,2,0,4,2);// 创建行文本框nameLineEdit = new QLineEdit();emailLineEdit = new QLineEdit();// [6]创建表单页面布局管理对象QFormLayout *formLayout = new QFormLayout;formLayout->addRow(tr("&Name:"), nameLineEdit);formLayout->addRow(tr("&Email:"), emailLineEdit);// [5]创建水平页面布局管理QHBoxLayout *gridhlayout = new QHBoxLayout;gridhlayout->addLayout(vlayout);gridhlayout->addLayout(gridLayout);// [3]创建垂直页面布局管理对象QVBoxLayout *layout = new QVBoxLayout;m_widget->setLayout(layout);layout->addLayout(formLayout);layout->addLayout(hlayout);layout->addLayout(gridhlayout);// 分页布局// [7.1]第一步:准备3个页面,每个页面放置一些组件QWidget *firstPageWidget = new QWidget;QWidget *secondPageWidget = new QWidget;QWidget *thirdPageWidget = new QWidget;// 准备页面组件:创建6个按钮,每个页面放置一个按钮button13 = new QPushButton("Page 1 button13");button14 = new QPushButton("Page 1 button14");button15 = new QPushButton("Page 2 button15");button16 = new QPushButton("Page 2 button16");button17 = new QPushButton("Page 3 button17");button18 = new QPushButton("Page 3 button18");// 创建3个页面布局,每个页面一个布局QVBoxLayout *page1layout = new QVBoxLayout;QHBoxLayout *page2layout = new QHBoxLayout;QVBoxLayout *page3layout = new QVBoxLayout;// 给分页布局添加组件page1layout->addWidget(button13);page1layout->addWidget(button14);page2layout->addWidget(button15);page2layout->addWidget(button16);page3layout->addWidget(button17);page3layout->addWidget(button18);// 设置分页布局firstPageWidget->setLayout(page1layout);secondPageWidget->setLayout(page2layout);thirdPageWidget->setLayout(page3layout);// [7.2]第二步:创建 QStackedLayout 页面布局管理对象,把分页添加到这个对象上QStackedLayout *stackedLayout = new QStackedLayout;// 向分页布局对象添加页面stackedLayout->addWidget(firstPageWidget);stackedLayout->addWidget(secondPageWidget);stackedLayout->addWidget(thirdPageWidget);// [7.3]第三步:设置分页切换方法,使用 QComboBox或QListWidget 实现QComboBox *pageComboBox = new QComboBox;pageComboBox->addItem(tr("Page 1"));pageComboBox->addItem(tr("Page 2"));pageComboBox->addItem(tr("Page 3"));connect(pageComboBox, SIGNAL(activated(int)), stackedLayout, SLOT(setCurrentIndex(int)));// [7.4]第四步:将 QStackedLayout 布局添加到主布局上,将分页切换组件添加到一个布局上vlayout->addWidget(pageComboBox);layout->addLayout(stackedLayout); // 向主页面添加分页布局}MainWindow::~MainWindow()
{delete ui;
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QLabel>
#include <QLineEdit>
#include <QStackedLayout>
#include <QListWidget>
#include <QHBoxLayout>int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow wondow;wondow.show();return a.exec();
}
2. 分割窗口
Qt中提供了 QSplitter 分离器类来实现窗口的分割,分割的窗口是用分割条隔开的,用户可以拖动分割条调整窗口的大小。
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QSplitter>
#include <QTextEdit>
#include <QHBoxLayout>namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = 0);~MainWindow();private:Ui::MainWindow *ui;private:QWidget *m_widget;private:QTextEdit *textEdit1; // 声明文本框1QTextEdit *textEdit2; // 声明文本框2QTextEdit *textEdit3; // 声明文本框3};#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);m_widget = new QWidget(this);this->setCentralWidget(m_widget);// [1]创建3个文本框textEdit1 = new QTextEdit();textEdit2 = new QTextEdit();textEdit3 = new QTextEdit();// [2]创建分离器对象QSplitter* splitter = new QSplitter;// [3]设置内部组件水平方向布局splitter->setOrientation(Qt::Horizontal);// [4]向分离器中,添加组件splitter->addWidget(textEdit1);splitter->addWidget(textEdit2);splitter->addWidget(textEdit3);/** [5]调整3个分割窗口的显示比例 1:1:2* setStretchFactor函数:* 第一个参数:窗口索引,从0开始* 第二个参数:拉伸比例* 第一个窗口索引0,拉伸1* 第二个窗口索引1,拉伸1* 第三个窗口索引2,拉伸2*/splitter->setStretchFactor(0, 1);splitter->setStretchFactor(1, 1);splitter->setStretchFactor(2, 2);/** [6]把分离器添加到窗口上* 创建一个layout* 添加组件的方式向layout添加分离器* 设置 layout 为程序的layout*/QHBoxLayout *hlayout = new QHBoxLayout;hlayout->addWidget(splitter);m_widget->setContentsMargins(5, 5, 5, 5);m_widget->setLayout(hlayout);// 设置窗口大小//m_widget->setFixedSize(800, 200);this->setFixedSize(800, 200);}MainWindow::~MainWindow()
{delete ui;
}
main.cpp
#include "mainwindow.h"
#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow w;w.show();return a.exec();
}
3. 滚动区域
当某个区域内的组件尺寸超过了预先设置好的范围时,可以使用QScrollArea提供的方法,生成滚动条,滚动显示组件内容。
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QScrollArea>
#include <QLabel>
#include <QHBoxLayout>namespace Ui {
class MainWindow;
}class MainWindow : public QWidget
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = 0);~MainWindow();private:Ui::MainWindow *ui;private:QLabel *scrollArealabel; // 声明一个标签};#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QWidget(parent)//,//ui(new Ui::MainWindow)
{//ui->setupUi(this);// [1]创建一个标签scrollArealabel = new QLabel;// 设置标签的最小尺寸,非常重要,否则有可能无法正常显示滚动条scrollArealabel->setMinimumSize(500,500);// 设置标签显示的内容,随便写点东西scrollArealabel->setText("helo world ");// [2]创建滚动区域,设置滚动区域关联的对象QScrollArea *scrollArea = new QScrollArea;// 把标签加到滚动区域,使用 setWidget() 函数scrollArea->setWidget(scrollArealabel);// 设置滚动区域的背景色scrollArea->setBackgroundRole(QPalette::Dark);// [3]创建一个布局QHBoxLayout *hlayout = new QHBoxLayout;// 把滚动区域加到布局上hlayout->addWidget(scrollArea);// 使布局生效this->setLayout(hlayout);// 设置窗口的大小,比标签的最小尺寸小,这样能显示滚动区域this->setFixedSize(400,400);
}MainWindow::~MainWindow()
{delete ui;
}
main.cpp
#include "mainwindow.h"
#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow w;w.show();return a.exec();
}
4. 停靠区域
在Qt中,停靠窗口主要是指可以在QMainWindow中停靠或可以浮动的独立窗口。停靠窗口有四个区域,每个窗口可以有自己的标题栏,用户可以通过拖拽的方式移动窗口。浮动窗口可以在下图中的白色区域内移动,QDockWidget 这个类提供了关于停靠窗口的方法。
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QDockWidget>
#include <QLabel>
#include <QPushButton>
#include <QTextEdit>
#include <QVBoxLayout>namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = 0);~MainWindow();private:Ui::MainWindow *ui;private:QLabel *label; // 设置一个标签QPushButton *button1; // 按钮1QPushButton *button2; // 按钮2QPushButton *button3; // 按钮3QTextEdit *textEdit; // 文本框
};#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);// [1]创建一个中心区域显示的文本框textEdit = new QTextEdit;textEdit->setText("main widget");// 设置文本框的大小textEdit->setFixedSize(300, 300);// 把文本框设置为程序中心窗口this->setCentralWidget(textEdit);// 设置组件与程序边框的距离this->setContentsMargins(15, 15, 15, 15);// 设置程序界面大小// this->setFixedSize(450, 330);// [2]创建组件label = new QLabel;label->setText("widget1");button1 = new QPushButton("aboutQt");button2 = new QPushButton("button2");button3 = new QPushButton("close");// 给两个按钮绑定槽,实现简单的功能connect(button1, SIGNAL(clicked()), qApp, SLOT(aboutQt()));// 关于QTconnect(button3, SIGNAL(clicked()), this, SLOT(close())); // 关闭程序// [3]创建页面布局,用于标签和按钮的布局QVBoxLayout *docklayout_1 = new QVBoxLayout;// 向布局添加组件docklayout_1->addWidget(label);docklayout_1->addStretch();docklayout_1->addWidget(button1);QVBoxLayout *docklayout_2 = new QVBoxLayout;// 向布局添加组件docklayout_2->addStretch();docklayout_2->addWidget(button2);docklayout_2->addWidget(button3);// [4]创建窗口组件QWidget *widget1 = new QWidget;QWidget *widget2 = new QWidget;// [5]设置窗口组件的布局widget1->setLayout(docklayout_1);widget2->setLayout(docklayout_2);// [6]创建停靠窗口,并把上面两个窗口添加到停靠窗口中QDockWidget *dock = new QDockWidget(tr("myDockWindow1"), this);// 设置停靠区域dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);// 设置停靠窗口的属性dock->setFeatures(QDockWidget::DockWidgetMovable); //停靠窗口可移动属性// 窗口 widget1 设置为停靠窗口dock->setWidget(widget1);// 设置停靠窗口的大小// dock->setFixedSize(100,100);// 设置边框颜色dock->setStyleSheet((QString::fromUtf8("border:1px solid gray")));// 向程序主界面添加停靠窗口this->addDockWidget(Qt::RightDockWidgetArea, dock);QDockWidget *dock1 = new QDockWidget(tr("myDockWindow2"), this);// 设置停靠区域dock1->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);// 设置停靠窗口的属性dock1->setFeatures(QDockWidget::AllDockWidgetFeatures); //具有停靠窗口的全部特性// 窗口 widget2 设置为停靠窗口dock1->setWidget(widget2);// 设置停靠窗口的大小// dock1->setFixedSize(100,200);// 设置边框颜色dock1->setStyleSheet((QString::fromUtf8("border:1px solid gray")));// 向程序主界面添加停靠窗口this->addDockWidget(Qt::RightDockWidgetArea, dock1);// [7]设置两个停靠窗口的位置,垂直排列splitDockWidget(dock, dock1, Qt::Vertical);
}MainWindow::~MainWindow()
{delete ui;
}
main.cpp
#include "mainwindow.h"
#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow w;w.show();return a.exec();
}
备注:参考文章
Qt零基础系列06:如何进行界面布局管理 - 知乎