Pyqt5系列(九)-基本布局管理

GUI的布局管理是GUI开发中非常重要的一个环节,一个设计良好的GUI界面,其对应的布局排布也是非常必须的。其中布局管理就是要管理窗口中部件的放置。常用两种方式来实现布局:绝对位置 布局(Absolute Layout)实现,布局类(QLayout)实现。

绝对位置 布局(Absolute Layout)主要是在程序中通过指定每一个组件显示的坐标和大小。由于影响绝对布局显示的因素很多(平台的差异,窗口大小的差异,显示字体大小等因素),所以在本文中主要以QLayout的基本布局进行说明。

布局定义

常用到的布局类有QHBoxLayout,QVBoxLayout,QGridLayout ,QFormLayout4种,分别水平排列布局,垂直排列布局,表格排列布局,以及。布局中最常用的方法有addWidget()和addLayout(),addWidget()方法用于在布局中插入控件,addLayout()用于在布局中插入子布局。

水平布局管理器(QHBoxLayout)可以把添加的控件以水平的顺序依次排开;
垂直布局管理器(QVBoxLayout)可以把添加的控件以垂直的顺序依次排开;
网格布局管理器(QGridLayout)可以以网格的形式,把添加的控件以一定矩阵排列;
窗体布局管理器(QFormLayout)可以以两列的形式排列所添加的控件

- 水平(垂直)布局管理:
QHBoxLayout,按照从左到右的顺序进行添加控件。
QVBoxLayout,按照从上到下的顺序进行添加控件。
QHBoxLayout和QVBoxLayout用法基本相同。这里以水平布局管理器QHBoxLayout为例来说明。

class QHBoxLayout(QBoxLayout)
 |  QHBoxLayout()
 |  QHBoxLayout(QWidget)

常用方法:
| addLayout(…)
| QBoxLayout.addLayout(QLayout, int stretch=0)
在box的底部添加布局,其中默认的拉伸因子为0

| addWidget(…)
| QBoxLayout.addWidget(QWidget, int stretch=0, Qt.Alignment alignment=0)
为布局中添加控件,stretch(拉伸因子)只适用与QBoxLayout,widget和box会随着stretch的变大而增大;alignment指定对齐的方式

| addSpacing(…)
| QBoxLayout.addSpacing(int)
通过该方法增加额外的space。

- 网格布局管理器:
将窗体分隔成行和列的网格来进行排列(可以认为是二维的数据排布)。通常可以使用函数addWidget()或者addLayout()来将被管理的widget或者layout添加到窗格中。也可以通过重载的函数addWidget()或者addLayout()的行和列跨度实现占据多个窗格。

class QGridLayout(QLayout)
 |  QGridLayout(QWidget)
 |  QGridLayout()

常用方法:

添加组件
| addWidget(…)
| QGridLayout.addWidget(QWidget)
| QGridLayout.addWidget(QWidget * widget, int row, int column, Qt.Alignment alignment = 0 )
QWidget:为所添加的组件
row:为组件要添加的行数,默认从0开始
column:为组件要添加到的列数,默认从0开始
alignment:对齐的方式

| QGridLayout.addWidget(QWidget * widget, int fromRow, int fromColumn, int rowSpan, int columnSpan, Qt.Alignment alignment = 0)
当添加的组件跨越很多行或者列的时候,使用该方法。
QWidget:为所添加的组件
fromRow:为组件起始的行数
fromColumn:为组件起始的列数
rowSpan:为组件跨越的行数
columnSpan:为组件跨越的列数
alignment:对齐的方式

| addLayout(…)
| QGridLayout.addLayout(QLayout, int, int, Qt.Alignment alignment=0)
| QGridLayout.addLayout(QLayout, int, int, int, int, Qt.Alignment alignment=0)

其中参数说明同addWidget.

- 窗体布局管理器:
在窗口中按照两列的形式排列控件,两列控件的类型可以根据使用的场景不同而不同。

class QFormLayout(QLayout)
 |  QFormLayout(QWidget parent=None)

常用方法:
| addRow(…)
| QFormLayout.addRow(QWidget, QWidget)
| QFormLayout.addRow(QWidget, QLayout)
| QFormLayout.addRow(str, QWidget)
| QFormLayout.addRow(str, QLayout)
| QFormLayout.addRow(QWidget)
| QFormLayout.addRow(QLayout)

示例说明

Pyqt5系列(九)-基本布局管理_第1张图片


如何实现如上的布局界面,先分析一下该界面的整体布局是如何排布的。
Pyqt5系列(九)-基本布局管理_第2张图片
QVBoxLayout(mainLayout)中包含QHBoxLayout和QFormLayout.其中QHBoxLayout中嵌套了QGridLayout和QVBoxLayout.
看一下具体的代码实现:

#-*- coding:utf-8 -*-
'''
Basic Layout
'''
__author__ = 'Tony Zhu'
import sys
from PyQt5.QtGui import  QPixmap
from PyQt5.QtWidgets import QWidget, QApplication, QGroupBox, QPushButton, QLabel, QHBoxLayout,  QVBoxLayout, QGridLayout, QFormLayout, QLineEdit, QTextEdit

class TianGong(QWidget):
    def __init__(self):
        super(TianGong,self).__init__()
        self.initUi()

    def initUi(self):
        self.createGridGroupBox()
        self.creatVboxGroupBox()
        self.creatFormGroupBox()
        mainLayout = QVBoxLayout()
        hboxLayout = QHBoxLayout()
        hboxLayout.addStretch()  
        hboxLayout.addWidget(self.gridGroupBox)
        hboxLayout.addWidget(self.vboxGroupBox)
        mainLayout.addLayout(hboxLayout)
        mainLayout.addWidget(self.formGroupBox)
        self.setLayout(mainLayout)

    def createGridGroupBox(self):
        self.gridGroupBox = QGroupBox("Grid layout")
        layout = QGridLayout()

        nameLabel = QLabel("中文名称")
        nameLineEdit = QLineEdit("天宫二号")
        emitLabel = QLabel("发射地点")
        emitLineEdit = QLineEdit("酒泉中心")
        timeLabel = QLabel("发射时间")
        timeLineEdit = QLineEdit("9月15日")
        imgeLabel = QLabel()
        pixMap = QPixmap("tiangong.png")
        imgeLabel.setPixmap(pixMap)
        layout.setSpacing(10) 
        layout.addWidget(nameLabel,1,0)
        layout.addWidget(nameLineEdit,1,1)
        layout.addWidget(emitLabel,2,0)
        layout.addWidget(emitLineEdit,2,1)
        layout.addWidget(timeLabel,3,0)
        layout.addWidget(timeLineEdit,3,1)
        layout.addWidget(imgeLabel,0,2,4,1)
        layout.setColumnStretch(1, 10)
        self.gridGroupBox.setLayout(layout)
        self.setWindowTitle('Basic Layout')

    def creatVboxGroupBox(self):
        self.vboxGroupBox = QGroupBox("Vbox layout")
        layout = QVBoxLayout() 
        nameLabel = QLabel("科研任务:")
        bigEditor = QTextEdit()
        bigEditor.setPlainText("搭载了空间冷原子钟等14项应用载荷,以及失重心血管研究等航天医学实验设备 "
                "开展空间科学及技术试验.")
        layout.addWidget(nameLabel)
        layout.addWidget(bigEditor)
        self.vboxGroupBox.setLayout(layout)

    def creatFormGroupBox(self):
        self.formGroupBox = QGroupBox("Form layout")
        layout = QFormLayout()
        performanceLabel = QLabel("性能特点:")
        performanceEditor = QLineEdit("舱内设计更宜居方便天宫生活")
        planLabel = QLabel("发射规划:")
        planEditor = QTextEdit()
        planEditor.setPlainText("2020年之前,中国计划初步完成空间站建设")
        layout.addRow(performanceLabel,performanceEditor)
        layout.addRow(planLabel,planEditor)

        self.formGroupBox.setLayout(layout)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = TianGong()
    ex.show()
    sys.exit(app.exec_())

代码分析:
L28~51:

    def createGridGroupBox(self):
        self.gridGroupBox = QGroupBox("Grid layout")
        layout = QGridLayout()

        nameLabel = QLabel("中文名称")
        nameLineEdit = QLineEdit("天宫二号")
        emitLabel = QLabel("发射地点")
        emitLineEdit = QLineEdit("酒泉中心")
        timeLabel = QLabel("发射时间")
        timeLineEdit = QLineEdit("9月15日")
        imgeLabel = QLabel()
        pixMap = QPixmap("tiangong.png")
        imgeLabel.setPixmap(pixMap)
        layout.setSpacing(10) 
        layout.addWidget(nameLabel,1,0)
        layout.addWidget(nameLineEdit,1,1)
        layout.addWidget(emitLabel,2,0)
        layout.addWidget(emitLineEdit,2,1)
        layout.addWidget(timeLabel,3,0)
        layout.addWidget(timeLineEdit,3,1)
        layout.addWidget(imgeLabel,0,2,4,1)
        layout.setColumnStretch(1, 10)
        self.gridGroupBox.setLayout(layout)
        self.setWindowTitle('Basic Layout')

定义QGridLayout布局。其中增加QGroupBox(有标题的组合框在它里面地其它不同窗口部件) ,将QGridLayout添加到QGroupBox中。
在本例中使用了不同参数重载的addWidget()方法。

在QLabel中显示图片。
pixMap = QPixmap(“tiangong.png”)
imgeLabel.setPixmap(pixMap)

layout.setColumnStretch(1, 10) 指定的行,设定其拉伸因子为10。

addWidget (self, QWidget, int, int, Qt.Alignment alignment = 0)
addWidget (self, QWidget, int, int, int, int, Qt.Alignment alignment = 0)
QWidget参数为需插入的控件对象,后面的两个int参数为插入的行和列,再后面两上int参数为跨度的行数和跨度的列数,alignment参数描述各控件的对齐方式。

L53~62:

    def creatVboxGroupBox(self):
        self.vboxGroupBox = QGroupBox("Vbox layout")
        layout = QVBoxLayout() 
        nameLabel = QLabel("科研任务:")
        bigEditor = QTextEdit()
        bigEditor.setPlainText("搭载了空间冷原子钟等14项应用载荷,以及失重心血管研究等航天医学实验设备 "
                "开展空间科学及技术试验.")
        layout.addWidget(nameLabel)
        layout.addWidget(bigEditor)
        self.vboxGroupBox.setLayout(layout)

定义QVBoxLayout布局。将QVBoxLayout添加到QGroupBox中。通过addWidget()方法增加所需的控件。

L64~75:

    def creatFormGroupBox(self):
        self.formGroupBox = QGroupBox("Form layout")
        layout = QFormLayout()
        performanceLabel = QLabel("性能特点:")
        performanceEditor = QLineEdit("舱内设计更宜居方便天宫生活")
        planLabel = QLabel("发射规划:")
        planEditor = QTextEdit()
        planEditor.setPlainText("2020年之前,中国计划初步完成空间站建设")
        layout.addRow(performanceLabel,performanceEditor)
        layout.addRow(planLabel,planEditor)
        self.formGroupBox.setLayout(layout

定义QFormLayout布局。将QFormLayout添加到QGroupBox中。通过addRow()方法增加所需的控件。

L19~25:

        mainLayout = QVBoxLayout()
        hboxLayout = QHBoxLayout()
        hboxLayout.addStretch()  
        hboxLayout.addWidget(self.gridGroupBox)
        hboxLayout.addWidget(self.vboxGroupBox)
        mainLayout.addLayout(hboxLayout)
        mainLayout.addWidget(self.formGroupBox)

定义QVBoxLayout类型的mainLayout,并将定义好的各个layout和groupbox按照嵌套的关系添加到mainLayout中。


关于各个layout中方法的详细使用可以参考pyqt的官网中的定义。

你可能感兴趣的:(Pyqt5,布局,pyqt,layout)