前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Qt学习笔记】3.布局

【Qt学习笔记】3.布局

作者头像
py3study
发布2020-01-08 16:53:28
8970
发布2020-01-08 16:53:28
举报
文章被收录于专栏:python3python3

一、手动布局

布局,Layout,就是把各个控件放在合适的位置,占据适当大小的空间。

在Qt中,使用布局器QLayout进行布局,QLayout本质上是一个工具类。

1、它为我们自动计算各个控件的大小和位置

2、当父窗口调整时,它根据既定策略Policy来调整各个子窗口的大小和位置

两个常用的QLayout类:

1、QHBoxLayout:横向布局

2、QVBoxLayout:纵向布局

(1)纵向布局:

V : Vertical,竖直方向上的

在纵向布局中,宽度信息被忽略,只关心它的高度

演示:

创建一个窗口MyWindow,包含一个QLineEdit 和一个 QPlainTextEdit,然后用QVBoxLayout进行托管

代码图下:

MyWindow.h:

代码语言:javascript
复制
#pragma once

#include <QWidget>

//添加头文件
#include <QVBoxLayout>
#include <QLineEdit>
#include <QPlainTextEdit>

class MyWindow : public QWidget
{
	Q_OBJECT

public:
	MyWindow(QWidget *parent);
	~MyWindow();

protected:
	QLineEdit* my_line_edit;
	QPlainTextEdit* my_text_edit;
};

MyWindow.cpp:

代码语言:javascript
复制
#include "MyWindow.h"

MyWindow::MyWindow(QWidget *parent)
	: QWidget(parent)
{
	//创建子控件对象
	my_line_edit = new QLineEdit(this);
	my_text_edit = new QPlainTextEdit(this);

	//创建布局器
	QVBoxLayout* layout = new QVBoxLayout(this);
	layout->addWidget(my_line_edit);
	layout->addWidget(my_text_edit);

	//使用布局器
	this->setLayout(layout);
}

MyWindow::~MyWindow()
{
}

main.cpp:

代码语言:javascript
复制
#include "Test3_1a_11_27.h"
#include "MyWindow.h"
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    //Test3_1a_11_27 w;
    //w.show();
	MyWindow w(NULL);
	w.resize(400, 300);
	w.move(100, 100);
	w.show();
    return a.exec();
}

运行程序,这时候会发现2个子窗口呈纵向布局,并且占满了整个主窗口:

wKioL1g7AzSBHGZdAAANeojCKYQ597.png
wKioL1g7AzSBHGZdAAANeojCKYQ597.png

改变主窗口的大小,两个子窗口的大小也会随之改变:

wKiom1g7AzXjV_2EAAAio78VOrk650.png
wKiom1g7AzXjV_2EAAAio78VOrk650.png
wKioL1g7AzXDrn5qAAAXD0mBHMI309.png
wKioL1g7AzXDrn5qAAAXD0mBHMI309.png

这时发现一个问题:

QLineEdit类型的子窗口只会改变宽度,而高度永远是固定的,

而QPlainTextEdit类型的子窗口宽度、高度都会跟着改变。

原因在于,这两个不通类型窗口的行为方式(Policy)是不同的

下面简单介绍几个属性:

SizePolicy:

前面提到过,表示窗口的行为方式

用于描述一个窗口(Widget)被调整大小(resizing)时,采用的策略。

在QSizePolicy类中定义了七种策略:

Fixed:使用sizeHint,不能更大,不能更小

Minimum:不能小于sizeHint,可以更大,但不需要更大

Maximum:不得大于sizeHint,可以更小

Preferred:优先使用sizeHint,可大可小

Expanding:使用sizeHint,越大越好

MinimumExpanding:不得小于sizeHint,越大越好

Ignored:忽略sizeHint,越大越好

SizePolicy的几个相关的函数:

代码语言:javascript
复制
//获取当前的policy
QSizePolicy QWidget::sizePolicy() const;


//设置新的policy(整体策略)
void setSizePolicy(QSizePolicy);    


//设置新的policy(横向策略,纵向策略)
void setSizePolicy(QSizePolicy::Policy horizontal, QSizePolicy::Policy vertical);

(PS:现在可以解释前面那个问题了:QLineEdit 和 QPlainTextEdit的纵向Policy分别为Fixed和Expanding)

SizeHint:

表示窗口的推荐大小

注意这个大小仅仅是推荐大小而不是最终大小

最终的实际大小是由布局器(QLayout)通过行为方式(SizePolicy)决定的

SizeHint的相关函数:

代码语言:javascript
复制
//向布局器声明自己需要的空间大小(推荐的尺寸)
virtual QSize sizeHint() const;

(2)横向布局:

H:Horizontal,水平方向上的

在横向布局中,高度信息被忽略,只关心它的宽度,其他要注意的同上

做一个有关手动布局的小练习:

使用学过的QPushButton、QLineEidt、QPlainTextEdit,结合布局器QHBoxLayout、QVBoxLayout,做一个简单的如下图所示的界面

wKiom1g8GvjCzR5tAAANkS5R2J0584.png
wKiom1g8GvjCzR5tAAANkS5R2J0584.png

代码如下:

代码语言:javascript
复制
/*
	练习:手动布局
	*/
	
	my_line_edit = new QLineEdit(this);
	my_text_edit = new QPlainTextEdit(this);
	my_button = new QPushButton(this);
	my_button->setText("Button");

	QHBoxLayout* layout_h = new QHBoxLayout();
	layout_h->addWidget(my_line_edit);
	layout_h->addWidget(my_button);
	
	QVBoxLayout* layout_v = new QVBoxLayout();
	layout_v->addLayout(layout_h);		//addLayout: 将整个布局器作为窗体托管给另一个布局器
	layout_v->addWidget(my_text_edit);

	this->setLayout(layout_v); //使用布局器,注意别忘了

二、可视化布局(Visual Layout)

截止到目前我们使用的布局方式都是传统的纯代码风格的手动布局

但是,当要设计的窗口比较复杂时,使用手动布局会变得非常麻烦,甚至难以实现。

因此 Qt框架下通常采用可视化布局的方式,使用设计器(Qt Designer)进行布局

这里定义窗体类,采用QtGuiClass:

wKiom1g8H33gMTVoAAB8uyQCQMs587.png
wKiom1g8H33gMTVoAAB8uyQCQMs587.png

创建完成后,在工程中向之前那样,增加了刚添加的 .h 和 .cpp 文件,此外,还增加了一个.ui文件,双击它,就可以打开Qt Designer工具,进行可视化设计了。

Qt Designer工具的Widget Box中有所有可用的控件,拖动即可添加,选中若干控件,屏幕正上方有之前介绍的布局器(Layout),可以进行水平、竖直方向上的组合以及拆散,如下图:

wKioL1g8I3PCKAjUAAArjZArwrY043.png
wKioL1g8I3PCKAjUAAArjZArwrY043.png

/***************************************************************

注意:使用设计器布局,最后要对整个Widget设置一下Layout

注意:使用设计器布局,最后要对整个Widget设置一下Layout

注意:使用设计器布局,最后要对整个Widget设置一下Layout

 (方法:点空白位置,或在对象查看器中选中主窗口,设置Layout)

***************************************************************/

使用上面的提到的方法,可以快速设计一个之前做过的界面:

wKiom1g8JOyiuFpZAAAX95igIao556.png
wKiom1g8JOyiuFpZAAAX95igIao556.png

可视化布局代码生成的过程:

这时候,编译,会发现多了一个ui_xxxxxxx.h的头文件:

wKiom1g8JSHSLvvJAABleKIwMv0399.png
wKiom1g8JSHSLvvJAABleKIwMv0399.png

该文件就是我们之前用设计器所做布局的代码实现,接下来就解释一下具体的过程。

还是刚刚的界面,用文本的格式打开MyWindow.ui

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MyWindow</class>
 <widget class="QWidget" name="MyWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>281</width>
    <height>247</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MyWindow</string>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout">
   <item>
    <layout class="QHBoxLayout" name="horizontalLayout">
     <item>
      <widget class="QLineEdit" name="lineEdit"/>
     </item>
     <item>
      <widget class="QPushButton" name="pushButton">
       <property name="text">
        <string>PushButton</string>
       </property>
      </widget>
     </item>
    </layout>
   </item>
   <item>
    <widget class="QPlainTextEdit" name="plainTextEdit"/>
   </item>
  </layout>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

这其实是一个xml文件,描述了我们所设计的窗体中的一切要素。

编译步骤:

1、界面布局,保存为*.ui

2、*.ui -> ui_*.h  (用编译程序uic进行转换)

3、启动C++的常规编译步骤

三、更多的布局参数

前面已经介绍过2个重要的布局参数:

size hint:     推荐大小

size policy:   策略

接下来再介绍一些同样重要的参数:

stretch factor:  拉伸因子

maximun size:   大小上限(0 ~ FFFFFF)

minimum size:   大小下限(0 ~ FFFFFF)

stretch factor(拉伸因子)

在同一方向上,如果两个控件都有拉伸的需求(比如说它们的Policy都设置成Expanding),那么就需要考虑它们的拉伸因子。 

举个例子,当两个Policy为Expanding的控件的stretch为1时,那么当放大窗口,这两个控件所分配的多余的空间之比为 1:1

尾巴:

这次基本上没什么要说的了 =  =

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-09-03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档