布局管理器简介

  • QT中提供了对界面组件进行布局管理的类,用于对界面组件进行管理,
  • 能够自动排列窗口中的界面组件
  • 窗口大小变化后,便会自动更新界面组件的大小。
  • 布局管理器可以自定义,从而达到更加个性化界面布局的效果
  • 布局管理器可以相互嵌套,完成所有常用的界面布局
  • QLayout是Qt中布局管理器的抽象基类,如下图所示:

QBoxLayout水平/垂直布局

QBoxLayout有两个子类:QHBoxLayout(水平)和QVBoxLayput(垂直)

比如垂直布局,表示将垂直方向分为一个个格子,如下图所示:

QVBoxLayput使用

int main(int argc, char *argv[])
{ QApplication a(argc, argv);
QWidget w; QVBoxLayout *layout=new QVBoxLayout; QPushButton btn1("test1",&w);
QPushButton btn2("test2",&w);
QPushButton btn3("test3",&w); btn1.setMaximumSize(,);
btn1.setMinimumSize(,);
btn2.setMaximumSize(,);
btn2.setMinimumSize(,);
btn3.setMaximumSize(,);
btn3.setMinimumSize(,); layout->addWidget(&btn1); //向布局管理器添加组件,实现自动布局
layout->addWidget(&btn2);
layout->addWidget(&btn3); w.setLayout(layout); //为部件设置布局管理器 layout->setSpacing(); w.show();
return a.exec();
}

QHBoxLayput使用

int main(int argc, char *argv[])
{ QApplication a(argc, argv);
   QWidget w; QHBoxLayout *layout=new QHBoxLayout; QPushButton btn1("test1",&w);
QPushButton btn2("test2",&w);
QPushButton btn3("test3",&w); btn1.setMaximumSize(,);
btn1.setMinimumSize(,);
btn2.setMaximumSize(,);
btn2.setMinimumSize(,);
btn3.setMaximumSize(,);
btn3.setMinimumSize(,); layout->addWidget(&btn1); //向布局管理器添加组件,实现自动布局
layout->addWidget(&btn2);
layout->addWidget(&btn3);
w.setLayout(layout); //为部件设置布局管理器 layout->setSpacing(); w.show();
return a.exec();
}

QBoxLayput相互嵌套

之前,我们写了QHBoxLayout(水平)和QVBoxLayput(垂直),但是只是单方面自动布局.

接下来,我们来使用嵌套,来实现水平+垂直自动布局,如下图所示:

示例代码如下:

int main(int argc, char *argv[])
{
QApplication a(argc, argv); QHBoxLayout *Hlayout1=new QHBoxLayout;
QHBoxLayout *Hlayout2=new QHBoxLayout;
QVBoxLayout *Vlayout=new QVBoxLayout; QWidget w; QPushButton btn1("test1",&w);
QPushButton btn2("test2",&w);
QPushButton btn3("test3",&w);
QPushButton btn4("test4",&w);
btn1.setMaximumSize(,);
btn1.setMinimumSize(,);
btn2.setMaximumSize(,);
btn2.setMinimumSize(,);
btn3.setMaximumSize(,);
btn3.setMinimumSize(,);
btn4.setMaximumSize(,);
btn4.setMinimumSize(,); Hlayout1->addWidget(&btn1); //水平布局: btn1 btn2
Hlayout1->addWidget(&btn2);
Hlayout1->setSpacing(); Hlayout2->addWidget(&btn3); //水平布局: btn3 btn4
Hlayout2->addWidget(&btn4);
Hlayout2->setSpacing(); Vlayout->addLayout(Hlayout1); //垂直布局: Hlayout1 Hlayout2
Vlayout->addLayout(Hlayout2);
Vlayout->setSpacing(); w.setLayout(Vlayout); //设置布局管理器,由于Vlayout管理着Hlayout1 Hlayout2,所以只填写一个即可 w.show(); return a.exec();
}

布局管理器比例系数

默认情况下,组件之间以等比例的方式改变组件大小.

其实用户也可以自定义组件之间比例系数,当窗口放大时,便来更新比例系数.

常用函数:

QBoxLayout::setStretch ( int index, int stretch );     //设置具体组件的拉伸系数
// index:表示布局管理器里的第几个组件
// stretch :拉伸系数 bool QBoxLayout::setStretchFactor ( QWidget * widget, int stretch );
//设置部件拉伸系数,如果存在*widget这个组件,则设置成功,返回true
bool QBoxLayout::setStretchFactor ( QLayout * layout, int stretch );
//设置布局拉伸系数, ,如果存在*layout这个组件,则设置成功,返回true

示例代码如下:

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QHBoxLayout *Hlayout1=new QHBoxLayout;
QHBoxLayout *Hlayout2=new QHBoxLayout;
QVBoxLayout *Vlayout=new QVBoxLayout;
QWidget w;
QPushButton btn1("test1",&w);
QPushButton btn2("test2",&w);
QPushButton btn3("test3",&w);
QPushButton btn4("test4",&w); btn1.setMinimumSize(,);
btn2.setMinimumSize(,);
btn3.setMinimumSize(,);
btn4.setMinimumSize(,); //设置大小策略,Expanding表示组件可扩展
btn1.setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
btn2.setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
btn3.setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
btn4.setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); Hlayout1->addWidget(&btn1); //水平布局: btn1 btn2
Hlayout1->addWidget(&btn2);
Hlayout1->setSpacing();
Hlayout2->addWidget(&btn3); //水平布局: btn3 btn4
Hlayout2->addWidget(&btn4);
Hlayout2->setSpacing(); Vlayout->addLayout(Hlayout1); //垂直布局: Hlayout1 Hlayout2
Vlayout->addLayout(Hlayout2); Vlayout->setStretchFactor(Hlayout1,);
Vlayout->setStretchFactor(Hlayout2,); Vlayout->setSpacing();
w.setLayout(Vlayout); //设置布局管理器,由于Vlayout管理着Hlayout1 Hlayout2,所以只填写一个即可
w.show();
return a.exec();
}

拉伸窗口后:

QGridLayout网格布局

以网格的方式管理界面组件,类似于:嵌套方式来使用QBoxLayout.

常用函数:

void  addWidget ( QWidget * widget, int row, int column, Qt::Alignment alignment =  );
// row column :表示将widget这个部件放在网格哪个位置 void addWidget ( QWidget * widget, int fromRow, int fromColumn, int rowSpan, int columnSpan, Qt::Alignment alignment = );
// row column :表示将widget这个部件放在网格哪个位置
// rowSpan: widget这个部件占多少行
// columnSpan: widget这个部件占多少列 void setColumnStretch(int column,int stretch); //设置列拉伸系数
                                  // column:设置布局管理器里的第几列,第1列为0
                                   void setRowStretch(int row,int stretch);    //设置行拉伸系数
                                  // row:设置的第几行

示例代码:

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGridLayout *layout=new QGridLayout;
QWidget w;
QPushButton btn1("test1",&w);
QPushButton btn2("test2",&w);
QPushButton btn3("test3",&w);
QPushButton btn4("test4",&w);
btn1.setMinimumSize(,);
btn2.setMinimumSize(,);
btn3.setMinimumSize(,);
btn4.setMinimumSize(,); //设置大小策略,Expanding表示组件可扩展
btn1.setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
btn2.setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
btn3.setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
btn4.setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); layout->addWidget(&btn1,,);
layout->addWidget(&btn2,,);
layout->addWidget(&btn3,,);
layout->addWidget(&btn4,,);
layout->setRowStretch(,); //设置第0行,比例为1
layout->setRowStretch(,); //设置第1行,比例为2
layout->setColumnStretch(,); //设置第0列,比例为1
layout->setColumnStretch(,); //设置第1列,比例为2
w.setLayout(layout); //设置布局管理器
w.show();
return a.exec();
}

拉伸窗口后:

QGridLayout相互嵌套

QGridLayout也支持布局管理器嵌套,比如,如下图所示:

示例代码:

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGridLayout *layout=new QGridLayout;
QVBoxLayout *Vlyt=new QVBoxLayout;
QWidget w;
QPushButton btn1("test1",&w);
QPushButton btn2("test2",&w);
QPushButton btn3("test3",&w);
QPushButton btn4("test4",&w);
QPushButton btn5("test5",&w);
btn1.setMinimumSize(,);
btn2.setMinimumSize(,);
btn3.setMinimumSize(,);
btn4.setMinimumSize(,); //btn4 btn5按钮需要缩小高度
btn5.setMinimumSize(,); //设置大小策略,Expanding表示组件可扩展
btn1.setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
btn2.setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
btn3.setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
btn4.setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
btn5.setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); Vlyt->addWidget(&btn4);
Vlyt->addWidget(&btn5);
layout->addWidget(&btn1,,);
layout->addWidget(&btn2,,);
layout->addWidget(&btn3,,);
layout->addLayout(Vlyt,,);
layout->setRowStretch(,); //设置第0行,比例为1
layout->setRowStretch(,); //设置第1行,比例为2
layout->setColumnStretch(,); //设置第0列,比例为1
layout->setColumnStretch(,); //设置第1列,比例为2
w.setLayout(layout);    //设置布局管理器
w.show();
return a.exec();
}

拉伸窗口后:

 

QFormLayout表单布局

以表单的方式管理界面组件,专为标签字段(组件)的形式创建的

表单布局也支持嵌套,可以管理子布局

常用函数:

addRow ( QWidget * label, QWidget * field );
addRow ( QWidget * label, QLayout * field );
addRow ( const QString & labelText, QWidget * field );
addRow ( const QString & labelText, QLayout * field ); void setLabelAlignment ( Qt::Alignment alignment );
           //设置标签对齐方式,比如标签左对齐 void setRowWrapPolicy ( RowWrapPolicy policy );
          //设置字段包装策略
          //比如参数WrapLongRows:表示给标签足够长空间,如果一行满足不了标签和字段显示,则将字段放在下行显示
          //参数QFormLayout::WrapAllRows: 示字段信息总在标签下面列出(占据整个行大小)

示例代码:

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget w(,Qt::WindowCloseButtonHint);
QLineEdit line1(&w);
QLineEdit line2(&w);
QLineEdit line3(&w);
QFormLayout *layout= new QFormLayout;
layout->addRow("姓名:",&line1);
layout->addRow("邮箱:",&line2);
layout->addRow("地址:",&line3);
layout->setRowWrapPolicy(QFormLayout::WrapAllRows); //设置字段总在标签下面
w.setLayout(layout);
w.show();
return a.exec();

效果:

QStackedLayout栈式布局

  • 将所有组件进行垂直管理
  • 并且每次只能有一个组件现在在屏幕上
  • 只有最顶层的组件才会被最终显示
  • 常用于图片播放,安装向导

特点

  • 组件大小一致且充满父组件的显示区
  • 能够自由切换需要显示的组件
  • 不能直接嵌套其它布局管理器,只能间接嵌套

常用函数:

int addWidget ( QWidget * widget );               //顺序添加组件

int insertWidget ( int index, QWidget * widget );       //插入组件

void removeWidget ( QWidget * widget );                 //删除组件

QWidget * currentWidget() ;                            //返回当前组件

int   currentIndex();                                  //返回当前组件索引值

void setCurrentIndex ( int index );                    //切换当前组件

void setCurrentWidget ( QWidget * widget );            //更换当前显示的组件

代码试验,通过定时器自动切换QStackedLayout

Widget.h

#ifndef WIDGET_H
#define WIDGET_H
#include <QtGui>
#include <QWidget>
#include <QObject> class Widget : public QWidget
{
Q_OBJECT
QTimer *timer;
QStackedLayout *Stack;
QPushButton btn1;
QPushButton btn2;
QPushButton btn3;
QPushButton btn4; private slots:
void time_handler(); public:
explicit Widget(QWidget *parent = ); }; #endif // WIDGET_H

Widget.cpp

#include "Widget.h"
#include <QDebug>
#include <QTimer> Widget::Widget(QWidget *parent) :
QWidget(parent),
btn1("test1",this),
btn2("test2",this),
btn3("test3",this),
btn4("test4",this)
{
btn1.setMinimumSize(,); Stack = new QStackedLayout; Stack->addWidget(&btn1);
Stack->addWidget(&btn2);
Stack->addWidget(&btn3);
Stack->addWidget(&btn4); Stack->setCurrentIndex();
this->setLayout(Stack); /*启动定时器*/
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(time_handler()));
timer->start(); //1000ms
} void Widget::time_handler()
{
static int index=;
Stack->setCurrentIndex((index++)%); //切换页面
qDebug()<<"Timer out";
}

main.cpp

int main(int argc, char *argv[])
{
QApplication app(argc,argv);
Widget w;
w.show();
return app.exec();
}

效果:

接下来试验间接嵌套

修改构造函数

Widget::Widget(QWidget *parent) :
QWidget(parent),
btn1("test1",this),
btn2("test2",this),
btn3("test3",this),
btn4("test4",this)
{
btn1.setMinimumSize(,); QWidget *w = new QWidget; /*设置多个子组件的父类*/
btn3.setParent(w);
btn4.setParent(w);
btn3.setMinimumSize(,);
btn4.setMinimumSize(,); /*通过其它布局管理器来管理*/
QVBoxLayout *Vlyt = new QVBoxLayout;
Vlyt->addWidget(&btn3);
Vlyt->addWidget(&btn4);
Vlyt->setSpacing();
w->setLayout(Vlyt); Stack = new QStackedLayout; Stack->addWidget(&btn1);
Stack->addWidget(&btn2);
Stack->addWidget(w);
Stack->setCurrentIndex();
this->setLayout(Stack); /*启动定时器*/
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(time_handler()));
timer->start(); //1000ms }

效果

11.QT-布局管理器(Box,Grid,Form,Stacked)的更多相关文章

  1. 第六章 Qt布局管理器Layout

    第六章 Qt布局管理器Layout 大家有没有发现一个现象,我们放置一个组件,给组件最原始的定位是给出这个控件的坐标和宽高值,这样Qt就知道这个组件的位置.当用户改变窗口的大小,组件还静静地呆在原来的 ...

  2. 初识Qt布局管理器

    Qt布局管理器的类有4种,它们分别为QHBoxLayout.QVBoxLayout.QGridLayout和QStackLayout.其中,QHBoxLayout实现水平布局,QVBoxLayout实 ...

  3. Qt——布局管理器

    教程地址 运行截图: 代码: #include "mainwindow.h" #include <QApplication> #include <QHBoxLay ...

  4. Qt 布局管理器

    在一个颜值当道的今天,无论买衣服,买车还是追星,颜值的高低已经变成了大家最看重的(不管男性女性都一样,千万别和我说你不是):而对于程序猿来说,开发一款软件,不再只注重逻辑和稳定性,美观和用户友好性也是 ...

  5. Qt布局管理器的使用(一)

    曾经对Qt的布局管理器掌握的还不清楚,今天特意学习了下.感觉收获还挺大的,特意拿出来和大家分享. 首先.要明确布局管理器的用处,及使我们的界面看起来比較整洁.美化.另外一点就是为了使我们的控件可以更随 ...

  6. QT5每日一学(五)QT布局管理器

    Qt中的布局管理器主要包括 QBoxLayout基本布局管理器 QGridLayout栅格布局管理器 QFormLayout窗体布局管理器 而基本布局管理器又分为QHBoxLayout水平布局管理器和 ...

  7. QT 布局管理器的使用

    很多的时候,需要布局管理器的使用, 在此介绍一下布局管理器的使用,直接上代码 #include "widget.h" #include "ui_widget.h" ...

  8. Tkinter 的三大布局管理器 pack、grid 和 place用法汇总

    学习python的tkinter免不了要对各个组件进行位置的排放与设定,常用的布局管理器有grid,pack和place.这三种均用于同一父组件下的组件布局,但是也是有区别的,先看下他们各自的含义吧. ...

  9. tkinter之grid布局管理器详解

    在很久之前,我发过一篇<tkinter模块常用参数>,里面已经几乎涵盖了tkinter的大部分教程. 好吧,其实也就是上一篇而已啦. 所谓布局,就是指控制窗体容器中各个控件(组件)的位置关 ...

随机推荐

  1. 其他—cooki和session

    cookie Cookie的由来 大家都知道HTTP协议是无状态的. 无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不 ...

  2. kubernetes 手绘画,先收藏一下

  3. Flow简易教程——安装篇

    .mydoc_h1{ margin: 0 0 1em; } .mydoc_h1_a{ color: #2c3e50; text-decoration: none; font-size: 2em; } ...

  4. EasyUI datagrid动态生成列

    任务描述:根据用户选择时间段,生成列数据,如图

  5. DevExpress 控件中GridControl的使用

    近期开发用到了DevExpress系列的控件,GridControl是我用到的Dev系列控件最多的一个控件.现在先来总结一下: 首先先写一个简单的小例子来简单介绍一下GridControl的用法: 1 ...

  6. 复习HTML+CSS(2)

    n  项目符号嵌套编号思路 标签的内容(文本.项目符号.表格.图片等)必须放在最底层标记中. n  图片标记(行内元素,单边标记) l  语法:<img 属性 = "值"&g ...

  7. POJ-2234 Matches Game---尼姆博奕裸题

    题目链接: https://vjudge.net/problem/POJ-2234 题目大意: 尼姆博奕裸题 思路: 直接异或 #include<iostream> #include< ...

  8. python手动设置递归调用深度

    python超出递归深度时会出现异常: RuntimeError: maximum recursion depth exceeded python默认的递归深度是很有限的,大概是900当递归深度超过这 ...

  9. AFNetworking 源码解读

    最近开始看第三方库优秀源码的计划,这是第一个,AFNetworking来和大家分享一下. AFNetworking 是一个十分优秀的网络框架,简单易用. 在开始之前,最好先了解一下NSURLSessi ...

  10. 使用javaMail实现简单邮件发送

    一.首先你要用来发送邮件的qq邮箱需要开通pop3/smtp服务,这个可以百度一下就知道了 二.导入所需要的jar包,我使用的是maven添加依赖 <dependency> <gro ...