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

我们进入正题,今天主要和大家分享一下Qt方面关于布局管理器的使用;

一、基本概念
   Qt 提供了几种在窗口部件上管理子窗口部件的基本方式。一共有3 种方法用于管理窗体上子窗口部件的布局:绝对位置法、人工布局法和布局管理器法。相比于使用固定尺寸和位置,布局提供了功能强大且极具灵活性的另一种方案。使用布局后,编程人员无需计算尺寸和位置,布局可以自动进行调整,符合用户屏幕、语言以及字体的要求。

1.绝对位置法
    这种方法是最原始的拖放窗口部件的方法。它对窗体的各个子窗口部件分配固定的大小和位置,是通过调用基类QWidget 提供的setGeometry()函数来实现的。
所以绝对位置法有很多缺点:
1> 用户无法改变窗口的大小,当父窗口改变时,子窗口不能做出相应的调整。
2>如果用户选择的字体太大或者翻译成多国语言,特别是俄语,很多都会显示不全被截断。
3> 对于不同风格的平台,这些窗口部件可能会具有并不合适的尺寸大小。
4>必须人工计算这些位置和大小。这样做不仅非常枯燥而且极易出错,并且还会让后
期的维护工作变得痛苦万分。
很显然,使用这种方式管理GUI 应用程序大大降低了程序员的开发效率,降低了应用
程序的质量和适应性。
 
2.人工布局法
    这种方法的核心是通过重载QWidget::resizeEvent(QResizeEvent*)函数来使得子窗口
的的大小尺寸总是和父窗口的大小成比例,也就在一定程度上减轻了计算量,但是在其中也
要通过setGeometry()函数来设置子窗口部件的位置和大小。在程序的规模比较小,并且不需要时常变更设计的情况下,绝对位置法勉强可以胜任。但是它就像前面的绝对位置法一样,仍然需要计算许多手写代码中的常量,尤其是当设计被改变的时候,这种情况更加突出,而且它并没有消除文本会被截断的危险。辅以社会自子窗口部件的大小提示,应该可以规避这种风险,但是这样会使代码变得尤为复杂。

3.布局管理器法
    这种方式是使用Qt 设计用户界面、组织管理Qt 窗口部件的最好方法。布局管理器为
窗口部件提供了能变化的默认值(sensible default sizes),可以随着窗口部件大小的变化,对子窗口部件的大小和位置做出适当的调整。
二、详细使用说明
    QLayout 类是Qt 的几何管理器的基类,它派生自QObject 类和QLayoutItem 类,是一
个抽象基类,必须被派生类所重新实现。它的派生类主要有QBoxLayout, QGridLayout, QFormLayout 以及QStackedLayout。而QBoxLayout
又有两个主要的Qt4 子类,QHBoxLayout 和QVBoxLayout

1、水平布局管理器:QHBoxLayout,按水平方向组织管理控件;
2、垂直布局管理器:QVBoxLayout,按垂直方向组织管理控件;
3、网格布局管理器:QGridLayout,按照二维网格组织管理控件;
4、表单布局管理器:QFormLayout,表单布局管理器主要用作管理界面上的输入窗口部件( input widgets)以及和它们相连的标签窗口部件(labels)。
5、栈布局管理器:QStackeLayout,类似于栈的方式管理控件,不过Qt设计器不知什么原因没有提供它的布局管理器(我认为开发人员觉得前几种已经能满足几乎所有的布局需要,栈布局使用太过复杂,不如用一个控件代替),提供了一个栈控件(QStackedWidget);在实际应用中使用前三种混合基本都能满足设计需求。
我们来看,第一种水平布局:

效果如图:1.1
                     [attachment=15390]
                                 1.1
第二种垂直布局:
效果如下图1.2
                                   [attachment=15391]
                                     1.2

第三种 网格布局:
效果如下图 1.3
                          [attachment=15392]
                                      1.3
第四种 表单布局
效果如下图 1.4
                         [attachment=15393]
                                              1.4
第五种是栈布局,我的4.7.0 版本,Qt Designer 的窗口部件盒没有可视化的提供对栈布局管理器的支持,只提供了一个栈部件QStackedWidget,作用与栈布局管理器类似。因此,在使用Qt Designer 绘制GUI界面时,完全可以使用QStackedWidget 来代替QStackedLayout。在此不做赘述。

2.1下面来讲讲案例:
     当然是用设计器拖出来最简单方便,我们后面再用代码写;
1.用设计器 添加五个控件;
2.选中是个button点击右键选择布局,我们选择栅格布局(你可以看情况自己选择合适的);
                            [attachment=15395]                 
                                      2.1
3.将刚才布局的控件和文本框一起选中,点击右键再选择你需要的布局方式(我们选择水平);

[attachment=15395] 
                                           2.2
4.效果图如下:
                       
                                    2.3

这里我们就要注意调整空白和控件之间间距的问题;
                   
                                     2.4
1.空白(margin)和间距(spacing)
    每种布局都有两个重要的属性,空白和间距。空白指的是整个布局四周距离窗体边缘
的距离;间距指的是布局管理器内部各个窗口部件之间的距离。空白属性即margin(),间距属性即spacing(),它们的默认值是有窗体的风格决定的。Qt 的默认风格下,子窗体部件的margin()的值是9 英寸。spacing()的值与margin()相同。如果要设置这两个值可以通过setMargin()和setSpacing()。注意,从Qt4.3 开始,margin()属性已经逐渐不再被Qt4 所推荐,更好的设置空白的方法是使用setContentsMargins()方法,
它的原型如下:
void QLayout::setContentsMargins ( int left, int top, int right, int bottom )
其中,left, top, right, 和bottom 表示环绕在布局周围的空白。对于QGridLayout 和QFormLayout,不要使用setSpacing()方法,而是要分别使用setHorizontalSpacing()和setVerticalSpacing()方法来设置水平和垂直方向

2.大小约束(size constraint)
    影响布局方式的另一种方法是设置它的子窗口部件的最大大小、最小大小或固定大小。这些是通过设置sizeConstraint 属性来完成的。该属性值是一个枚举常量,定义了布局的大小约束的模式。表列出了它所有可能的取值,它的默认值是QLayout::SetDefaultConstraint。获取和设置该属性值可以通过QWidget::layout()来获取主窗口部件的布局管理器,然后可以调用QLayout::sizeConstraint()函数来查看当前的设置情况,然后再通过QLayout::setSizeConstraint()函数来设置该布局管理器的sizeConstraint 属性。这两种函数的原型如下:SizeConstraint sizeConstraint () const
void setSizeConstraint ( SizeConstraint )其中,SizeConstraint 的取值可以在QLayout类的枚举中得到;
QLayout::SetDefaultConstraint 0 主窗口部件的最小尺寸设置为minimumSize(),除非该窗口部件已经有一个最小尺寸
QLayout::SetFixedSize 3 主窗口部件的尺寸设置为sizeHint(),并且不允许改变该窗口部件的尺寸
QLayout::SetMinimumSize 2 主窗口部件的最小尺寸设置为minimumSize(),并且该窗口部件不能够变得更小
QLayout::SetMaximumSize 4 主窗口部件的最大尺寸设置为maximumSize(),并且该窗口部件不能够变得更大
QLayout::SetMinAndMaxSize 5 主窗口部件的最小尺寸设置为minimumSize(),最大尺寸设置为

3.大小策略(size policy)
    一个窗口部件的大小策略会告诉布局系统应该如何对它进行拉伸或收缩。Qt 为它所有
的内置窗口部件都提供了合理的默认大小策略值,但是由于不可能为每一种可能产生的布局
都提供唯一的默认值,所以在一个窗体中,开发人员改变它上面的一个或两个窗口部件的大
小策略是非常普遍的现象。一个QSizePolicy 既包含一个水平分量也包含一个垂直分量。
可以通过QSizePolicy 找到对应的枚举值;

4.伸缩因子(stretch factor)
    除了大小策略中包含的水平方向和垂直方向两个分量之外, QSizePolicy 类还保存了水平方向和垂直方向的一个伸缩因子。这些伸缩因子可以用来说明在增大窗体时,对不同的子窗口部件应使用的不同放大比例。即需要设置QSizePolicy::horizontalStretch 和
QSizePolicy::verticalStretch 的值来实现。默认情况下,被布局管理器组合在一起的窗
口部件的伸缩因子是相等的,都为0。

2.2 移除布局
选择想要移除的布局,点击右键或者如下图在设计器工具栏上有个“打破布局”
如图:
           [attachment=15398]
                               2.5
2.3 一些快捷键
    常见的布局操作所对应的快捷键。
水平布局Ctrl+1 将选中的界面元素置于一个水平布局中;
垂直布局Ctrl+2 将选中的界面元素置于一个垂直布局中;
栅格布局Ctrl+5 将选中的界面元素置于一个栅格布局中;
表单布局Ctrl+6 将选中的界面元素置于一个表单布局中;
分裂器水平布局Ctrl+3 创建一个分裂器水平布局,并将选中的界面元素置于其中;
分裂器垂直布局Ctrl+4 创建一个分裂器垂直布局,并将选中的界面元素置于其中;
调整大小Ctrl+J 调整布局的大小,以使得位于其中的元素能够恰当的显示自身内容。关于这方面的内容,可以参见QWidget::adjustSize()函数;
破除布局Ctrl+0 破除选中的布局;

2.4 手写代码
    QWidget  *pWidget = new QWidget;
    pWidget->setWindowTitle("Calculator");
    pWidget->show();
    QLineEdit *pText = new QLineEdit(pWidget);
    pText->setMinimumSize(150,100);

QPushButton *pBtnAdd = new QPushButton("+",pWidget);
    QPushButton *pBtnSub = new QPushButton("-",pWidget);
    QPushButton *pBtnMul= new QPushButton("*",pWidget);
    QPushButton *pBtnDiv= new QPushButton("/",pWidget);

QVBoxLayout *pVBox = new QVBoxLayout(pWidget);
    QGridLayout *pGBox = new QGridLayout();

pVBox->addWidget(pBtnAdd);
    pVBox->addWidget(pBtnSub);
    pVBox->addWidget(pBtnMul);
    pVBox->addWidget(pBtnDiv);
    pVBox->setSpacing(10);
    pWidget->setLayout(pVBox);

pGBox->addWidget(pBtnAdd,0,0);
    pGBox->addWidget(pBtnSub,0,1);
    pGBox->addWidget(pBtnMul,1,0);
    pGBox->addWidget(pBtnDiv,1,1);

pVBox->addWidget(pText);
    pVBox->addLayout(pGBox);
    pVBox->setMargin(12);
pWidget->setLayout(pVBox);
 
效果如下图2.6:
                  
                                  2.6
2.5 总结
    当界面元素较为复杂时,应该毫不犹豫的尽量使用网格布局,而不是使用水平和垂直布局的组合或者嵌套的形式,因为在多数情况下,后者往往会使“局势”更加复杂而难以控制。网格布局赋予了界面设计器更大的自由度来排列组合界面元素,而仅仅带来了微小的复杂度开销。当要设计的界面是一种类似于两列和若干行组成的形式时,使用表单布局要比网格布局更为方便些。
   上面分享了自己关于布局的基础使用方式的理解,若有不对之处敬请指正

Qt 布局管理器的更多相关文章

  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布局管理器的使用(一)

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

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

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

  6. QT 布局管理器的使用

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

  7. Qt中的布局管理器

    1. 布局管理器提供相关的类对界面组件进行布局管理,能够自动排列窗口中的界面组件,窗口变化后能自动更新界面组件的大小. 2. QLayout是Qt布局管理器的抽象基类,通过继承QLayout实现了功能 ...

  8. Qt 学习之路 2(11):布局管理器

    Home / Qt 学习之路 2 / Qt 学习之路 2(11):布局管理器 Qt 学习之路 2(11):布局管理器  豆子  2012年9月4日  Qt 学习之路 2  70条评论 所谓 GUI 界 ...

  9. Qt之布局管理器

    简述 Qt的布局系统提供了一个简单的和强有力的方式,来自动排列窗口子控件布局. 所有QWidget子类可以使用布局来管理他们的子控件.QWidget::setLayout()函数可以为一个控件布局.当 ...

随机推荐

  1. jquery validate 多种使用方式

    前言:jQuery.validator是一款非常不错的表单验证插件,验证方式非常简单方便,它还对HTML5做了兼容处理,了解了验证规则,就基本掌握了它的使用,下面就让我一一道来 jQuery.vali ...

  2. Unity3D动作资源(AnimatinClip)优化

    能做到去掉Scale曲线,降低浮点精度 using System; using UnityEngine; using System.Collections; using System.Collecti ...

  3. yii---解决post请求出现500错误

    在使用yii框架的时候,在发送数据请求的时候,POST请求会出现500错误,这是因为yii2开启了防御csrf的攻击机制,可去先去掉,在控制器里去掉:public $enableCsrfValidat ...

  4. UVM phase的用法研究【zz】

    原文地址:http://bbs.eetop.cn/viewthread.php?tid=383872&extra=&authorid=828160&page=1 我相信很多朋友 ...

  5. 关于jquery的css的一些知识

    Query实例CSS 样式表动态选择本实例主要说的还是jquery的选择器,关于jquery的css的一些知识用类似 $("li").css("cursor", ...

  6. SPOJ Distinct Substrings【后缀数组】

    Given a string, we need to find the total number of its distinct substrings. Input T- number of test ...

  7. java 中静态变量(类变量)与实例变量 静态方法与实例方法

    静态变量: 在类内部中,方法的外部声明的对象而且加上static; 实例变量: 在类内部中,声明不需要加static; 比如: public class Demo{ int i1=0; static ...

  8. ubuntu16.04下安装sublime_text

    1 在终端输入: sudo add-apt-repository ppa:webupd8team/sublime-text-3 添加sublime text3的软件源: 2 sudo apt-get ...

  9. Spring Cloud微服务开发笔记5——Ribbon负载均衡策略规则定制

    上一篇文章单独介绍了Ribbon框架的使用,及其如何实现客户端对服务访问的负载均衡,但只是单独从Ribbon框架实现,没有涉及spring cloud.本文着力介绍Ribbon的负载均衡机制,下一篇文 ...

  10. Oracle体系结构之控制文件管理

    控制文件作用:记录了数据库的结构和行为,有多少个数据文件,日志文件及其位置名称,状态,维护数据库的一致性,即记录了数据库的启动SCN号和终止SCN号. 控制文件的位置和个数记录在参数文件中,通常控制文 ...