布局管理器
布局管理器
-
作用:能够自动排列窗口中的界面组件
-
窗口变化后自动更新界面组件的大小
-
QLayout是Qt中的抽象基类
一. 水平布局管理器 (QHBoxLayout )
- 水平布局管理器QHBoxLayout继承自QBoxLayout这个类
-
实验代码
//水平布局管理器 void Widget::testHBoxLayout() { //定义一个水平布局管理器 QHBoxLayout* layout = new QHBoxLayout(); TestBtn1.setText("Test Button 1"); TestBtn1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn1.setMinimumSize(160, 30); TestBtn2.setText("Test Button 2"); TestBtn2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn2.setMinimumSize(160, 30); TestBtn3.setText("Test Button 3"); TestBtn3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn3.setMinimumSize(160, 30); TestBtn4.setText("Test Button 4"); TestBtn4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn4.setMinimumSize(160, 30); //每个组件的间距 layout->setSpacing(30); //将四个按钮组件放到布局管理器中 layout->addWidget(&TestBtn1); layout->addWidget(&TestBtn2); layout->addWidget(&TestBtn3); layout->addWidget(&TestBtn4); //使水平布局管理器生效 setLayout(layout); }
- 效果如下
二. 垂直布局管理器 ( QVBoxLayout)
- 垂直布局管理器QHBoxLayout继承自QBoxLayout这个类
-
实验代码
//垂直布局管理器 void Widget::testVHBoxLayout() { QHBoxLayout* hLayout1 = new QHBoxLayout(); QHBoxLayout* hLayout2 = new QHBoxLayout(); QVBoxLayout* vLayout = new QVBoxLayout(); TestBtn1.setText("Test Button 1"); TestBtn1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn1.setMinimumSize(160, 30); TestBtn2.setText("Test Button 2"); TestBtn2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn2.setMinimumSize(160, 30); hLayout1->setSpacing(10); hLayout1->addWidget(&TestBtn1); hLayout1->addWidget(&TestBtn2); TestBtn3.setText("Test Button 3"); TestBtn3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn3.setMinimumSize(160, 30); TestBtn4.setText("Test Button 4"); TestBtn4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn4.setMinimumSize(160, 30); hLayout2->setSpacing(10); hLayout2->addWidget(&TestBtn3); hLayout2->addWidget(&TestBtn4); vLayout->setSpacing(10); vLayout->addLayout(hLayout1); vLayout->addLayout(hLayout2); setLayout(vLayout); }
三. 布局管理器的嵌套
-
布局管理器可以嵌套使用,这里使用水平布局管理器管理竖直布局管理器,实现了一个网格布局管理
void Widget::testVHBoxLayout() { QHBoxLayout* hLayout1 = new QHBoxLayout(); QHBoxLayout* hLayout2 = new QHBoxLayout(); QVBoxLayout* vLayout = new QVBoxLayout(); TestBtn1.setText("Test Button 1"); TestBtn1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn1.setMinimumSize(160, 30); TestBtn2.setText("Test Button 2"); TestBtn2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn2.setMinimumSize(160, 30); hLayout1->setSpacing(10); hLayout1->addWidget(&TestBtn1); hLayout1->addWidget(&TestBtn2); TestBtn3.setText("Test Button 3"); TestBtn3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn3.setMinimumSize(160, 30); TestBtn4.setText("Test Button 4"); TestBtn4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn4.setMinimumSize(160, 30); hLayout2->setSpacing(10); hLayout2->addWidget(&TestBtn3); hLayout2->addWidget(&TestBtn4); vLayout->setSpacing(10); vLayout->addLayout(hLayout1); vLayout->addLayout(hLayout2); setLayout(vLayout); }
四. 网格布局管理器 (QGridLayout)
-
实验代码
void Widget::testGridLayout1() { //以网格(二维)的方式管理布局 QGridLayout* layout = new QGridLayout(); TestBtn1.setText("Test Button 1"); TestBtn1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn1.setMinimumSize(160, 30); TestBtn2.setText("Test Button 2"); TestBtn2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn2.setMinimumSize(160, 30); TestBtn3.setText("Test Button 3"); TestBtn3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn3.setMinimumSize(160, 30); TestBtn4.setText("Test Button 4"); TestBtn4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn4.setMinimumSize(160, 30); layout->setSpacing(10); //添加组件的时候需要设置组件在网格布局管理中的坐标 layout->addWidget(&TestBtn1, 0, 0); layout->addWidget(&TestBtn2, 0, 1); layout->addWidget(&TestBtn3, 1, 0); layout->addWidget(&TestBtn4, 1, 1); //第0行高:第1行高 = 1:3 layout->setRowStretch(0, 1); layout->setRowStretch(1, 3); //第0列宽:第1列宽 = 1:3 layout->setColumnStretch(0, 1); layout->setColumnStretch(1, 3); setLayout(layout); }
-
addWidget的另一个重载用法
void Widget::testGridLayout2() { QGridLayout* layout = new QGridLayout(); TestBtn1.setText("Test Button 1"); TestBtn1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn1.setMinimumSize(160, 30); TestBtn2.setText("Test Button 2"); TestBtn2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn2.setMinimumSize(160, 30); TestBtn3.setText("Test Button 3"); TestBtn3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn3.setMinimumSize(160, 30); TestBtn4.setText("Test Button 4"); TestBtn4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn4.setMinimumSize(160, 30); layout->setSpacing(10); //添加部件,addWidget的一个重载函数 addWidget(组件,x坐标,y坐标,高比,宽比) layout->addWidget(&TestBtn1, 0,0, 1,1); layout->addWidget(&TestBtn2, 0,1, 1,1); layout->addWidget(&TestBtn3, 2,0, 1,2); layout->addWidget(&TestBtn4, 3,0, 1,2); setLayout(layout); }
五. 栈式布局管理器
- 栈式布局管理器QStackedLayout
-
栈式布局管理器的特点:
所有组件在垂直于屏幕的方向上被管理
每次只有一个组件会显示在屏幕上
只有顶层的组件会被最终显示
-
实验
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QPushButton> class Widget : public QWidget { Q_OBJECT private: QPushButton TestBtn1; QPushButton TestBtn2; QPushButton TestBtn3; QPushButton TestBtn4; void initControl(); private slots: void timerTimeout(); public: Widget(QWidget *parent = 0); ~Widget(); }; #endif // WIDGET_H
#include "Widget.h" #include "ui_Widget.h" #include <QStackedLayout> #include <QHBoxLayout> #include <QtCore> #include <QDebug> Widget::Widget(QWidget *parent) : QWidget(parent), TestBtn1(this), TestBtn2(this), TestBtn3(this), TestBtn4(this) { initControl(); } void Widget::initControl() { //栈式布局管理器 QStackedLayout* sLayout = new QStackedLayout(); QHBoxLayout* hLayout = new QHBoxLayout(); QWidget* widget = new QWidget(); QTimer* timer = new QTimer(this); TestBtn1.setText("Button1 : hello world"); TestBtn2.setText("Button2 : keep coding"); TestBtn3.setText("Button3 : aloha "); TestBtn4.setText("Button4 : yi~ yeah~"); //修改Button2和Button3的父组件为widget TestBtn2.setParent(widget); TestBtn3.setParent(widget); //使用水平布局管理器管理widget上的组件Button2和Button3 hLayout->addWidget(&TestBtn2); hLayout->addWidget(&TestBtn3); widget->setLayout(hLayout); //将Button1放到栈式布局管理器中第一个位置,即顶层位置 sLayout->addWidget(&TestBtn1); // 0 //放置到栈式布局管理器中的第二个组件是widget,由水平布局管理器hLayout管理组件 sLayout->addWidget(widget); // 1 //放置到栈式布局管理器中的第三个组件是Button4 sLayout->addWidget(&TestBtn4); // 2 sLayout->setCurrentIndex(1); //设置从第几个组件开始显示,下标从0开始,此demo中是0~2 setLayout(sLayout); //使栈式布局管理器生效 connect(timer, SIGNAL(timeout()), this, SLOT(timerTimeout())); timer->start(2000); } void Widget::timerTimeout() { QStackedLayout* sLayout = dynamic_cast<QStackedLayout*>(layout()); if( sLayout != NULL ) { int index = (sLayout->currentIndex() + 1) % sLayout->count(); sLayout->setCurrentIndex(index); } } Widget::~Widget() { }