注:原创不易,转载请务必注明原作者和出处,感谢支持!

一 写在开头

1.1 本文内容

本文内容为PyQt5中的布局管理。具体内容为:

  1. 绝对布局
  2. 布局类
    • 水平布局(QHBoxLayout)
    • 垂直布局(QVBoxLayout)
    • 网格布局(QGridLayout)
    • 表单布局(QFormLayout)
  3. 嵌套布局
  4. 布局管理器QSplitter

二 绝对布局

绝对布局主要用到两个方法,分别是move()和setGeometry()。

#!/usr/bin/env python3
# -*- coding: utf-8 -*- import sys
from PyQt5.QtWidgets import QWidget, QLabel, QApplication class Window(QWidget):
def __init__(self):
super().__init__()
self.initUI() def initUI(self):
lb1 = QLabel('欢迎', self)
lb1.move(15, 10)
lb2 = QLabel('学习', self)
lb2.move(35, 40)
lb3 = QLabel('PyQt 5', self)
lb3.move(55, 70)
self.setGeometry(300, 300, 250, 150)
self.setWindowTitle('PyQt 5中的绝对定位')
self.show() if __name__ == '__main__':
app = QApplication(sys.argv)
w = Window()
sys.exit(app.exec_())

绝对布局的优点:

  • 可以直接定位每个控件的位置

绝对布局的缺点:

  • 如果改变一个窗口的大小,窗口中控件的大小和位置不会随之改变
  • 所生成的窗口在不同的操作系统下看起来可能不一样
  • 在程序中改变字体时可能会破坏布局
  • 如果修改布局,比如新增一个控件,就必须全部重新布局,既烦琐又费时

三 布局类

3.1 水平布局(QHBoxLayout)和垂直布局(QVBoxLayout)

本小节涉及到的方法及其描述如下:

方法 描述
addLayout(self, QLayout, stretch = 0) 在窗口中添加布局,stretch为伸缩量,默认为0
addWidget(self, QWidget, stretch, Qt.Alignment alignment) 在布局中添加控件,stretch为伸缩量,alignment为对齐方式
addSpacing(self, int) 添加伸缩量,具体使用方法见下面的例子

对齐方式Qt.Alignment可能取值有:

参数 描述
Qt.AlignLeft 水平居左对齐
Qt.AlignRight 水平居右对齐
Qt.AlignCenter 水平居中对齐
Qt.AlignJustify 水平两端对齐
Qt.AlignTop 垂直靠上对齐
Qt.AlignBottom 垂直靠下对齐
Qt.AlignVCenter 垂直居中对齐

3.2 水平布局和垂直布局实例

#!/usr/bin/env python3
# -*- coding: utf-8 -*- import sys
from PyQt5.QtWidgets import QWidget, QPushButton, QHBoxLayout, QApplication class Window(QWidget):
def __init__(self):
super().__init__() hbox = QHBoxLayout()
hbox.addWidget(QPushButton(str(1)))
hbox.addWidget(QPushButton(str(2)))
hbox.addWidget(QPushButton(str(3)))
hbox.addWidget(QPushButton(str(4)))
hbox.addWidget(QPushButton(str(5)))
self.setLayout(hbox) self.setWindowTitle('QHBoxLayout')
self.show() if __name__ == '__main__':
app = QApplication(sys.argv)
w = Window()
sys.exit(app.exec_())

#!/usr/bin/env python3
# -*- coding: utf-8 -*- import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QWidget, QPushButton, QHBoxLayout, QApplication class Window(QWidget):
def __init__(self):
super().__init__() hbox = QHBoxLayout()
hbox.addWidget(QPushButton(str(1)), 0, Qt.AlignTop)
hbox.addWidget(QPushButton(str(2)), 0, Qt.AlignTop | Qt.AlignLeft)
hbox.addWidget(QPushButton(str(3)), 0)
hbox.addWidget(QPushButton(str(4)), 0, Qt.AlignLeft | Qt.AlignBottom)
hbox.addWidget(QPushButton(str(5)), 0, Qt.AlignTop) self.setLayout(hbox)
self.setWindowTitle('水平布局')
self.show() if __name__ == '__main__':
app = QApplication(sys.argv)
w = Window()
sys.exit(app.exec_())

关于addSpacing()的用法见下面的实例。

#!/usr/bin/env python3
# -*- coding: utf-8 -*- import sys
from PyQt5.QtWidgets import QWidget, QPushButton, QHBoxLayout, QApplication class Window(QWidget):
def __init__(self):
super().__init__() btn1 = QPushButton()
btn2 = QPushButton()
btn3 = QPushButton()
btn1.setText(str(1))
btn2.setText(str(2))
btn3.setText(str(3)) # addSpacing(1)表示设置伸缩量为1
hbox = QHBoxLayout()
hbox.addStretch(1)
hbox.addWidget(btn1)
hbox.addStretch(1)
hbox.addWidget(btn2)
hbox.addStretch(1)
hbox.addWidget(btn3)
hbox.addStretch(1) self.setLayout(hbox)
self.setWindowTitle('addStretch')
self.show() if __name__ == '__main__':
app = QApplication(sys.argv)
w = Window()
sys.exit(app.exec_())

#!/usr/bin/env python3
# -*- coding: utf-8 -*- import sys
from PyQt5.QtWidgets import QWidget, QPushButton, QHBoxLayout, QApplication class Window(QWidget):
def __init__(self):
super().__init__() btn1 = QPushButton()
btn2 = QPushButton()
btn3 = QPushButton()
btn1.setText(str(1))
btn2.setText(str(2))
btn3.setText(str(3)) hbox = QHBoxLayout()
hbox.addStretch(0)
hbox.addWidget(btn1)
hbox.addWidget(btn2)
hbox.addWidget(btn3)
hbox.addStretch(0) self.setLayout(hbox)
self.setWindowTitle('addStretch')
self.show() if __name__ == '__main__':
app = QApplication(sys.argv)
w = Window()
sys.exit(app.exec_())

3.3 网格布局(QGridLayout)

网格布局需要用到的方法及其描述如下。

方法 描述
addWidget(QWidget widget, int row, int col, int alignment = 0) 给网格布局添加控件。
widget:要添加的控件
row:位置所在行
col:位置所在列
alignment:对齐方式
addWidget(QWidget widget, int fromRow, int fromColumn, int rowSpan, int columnSpan, int alignment) 当所添加的控件跨越多行或多列时,使用这个函数
fromRow:起始行
fromColumn:起始列
rowSpan:控件跨越的行
columnSpan:控件跨越的列
setSpacing(int spacing) 设置控件在水平和垂直方向的间隔

3.4 网格布局实例

#!/usr/bin/env python3
# -*- coding: utf-8 -*- import sys
from PyQt5.QtWidgets import QWidget, QGridLayout, QPushButton, QApplication class Window(QWidget):
def __init__(self):
super().__init__()
self.initUI() def initUI(self):
grid = QGridLayout()
self.setLayout(grid) names = ['Cls', 'Back', '', 'Close',
'7', '8', '9', '/',
'4', '5', '6', '*',
'1', '2', '3', '-',
'0', '.', '=', '+']
positions = [(i, j) for i in range(5) for j in range(4)]
for position, name in zip(positions, names):
if name == '':
continue
btn = QPushButton(name)
grid.addWidget(btn, *position) self.move(300, 150)
self.setWindowTitle('网格布局')
self.show() if __name__ == '__main__':
app = QApplication(sys.argv)
w = Window()
sys.exit(app.exec_())

#!/usr/bin/env python3
# -*- coding: utf-8 -*- import sys
from PyQt5.QtWidgets import QWidget, QLabel, QLineEdit, QTextEdit, QGridLayout, QApplication class Window(QWidget):
def __init__(self):
super().__init__()
self.initUI() def initUI(self):
title = QLabel('标题')
author = QLabel('提交人')
review = QLabel('申告内容') titleEdit = QLineEdit()
authorEdit = QLineEdit()
reviewEdit = QTextEdit() grid = QGridLayout()
grid.setSpacing(10)
self.setLayout(grid) grid.addWidget(title, 0, 0)
grid.addWidget(titleEdit, 0, 1)
grid.addWidget(author, 1, 0)
grid.addWidget(authorEdit, 1, 1)
grid.addWidget(review, 2, 0)
grid.addWidget(reviewEdit, 2, 1, 2, 1) self.setGeometry(300, 300, 350, 300)
self.setWindowTitle('故障申报')
self.show() if __name__ == '__main__':
app = QApplication(sys.argv)
w = Window()
sys.exit(app.exec_())

3.5 表单布局(QFormLayout)

QFormLayout是label-field式的表单布局,顾名思义,就是实现表单方式的布局。表单是提示用户进行交互的一种模式,其主要由两列组成,第一列用于显示信息,给用户提示,一般叫做label域;第二列需要用户进行选择或者输入,一般叫做field域。label与field的关系就是label关联field。

QFormLayout需要用到addRow(label, field)方法。

3.6 表单布局实例

#!/usr/bin/env python3
# -*- coding: utf-8 -*- import sys
from PyQt5.QtWidgets import QWidget, QFormLayout, QLabel, QLineEdit, QApplication class Window(QWidget):
def __init__(self):
super().__init__()
self.initUI() def initUI(self):
form = QFormLayout() lb1 = QLabel('标签1')
le1 = QLineEdit()
lb2 = QLabel('标签2')
le2 = QLineEdit()
lb3 = QLabel('标签3')
le3 = QLineEdit() form.addRow(lb1, le1)
form.addRow(lb2, le2)
form.addRow(lb3, le3) self.resize(400, 100)
self.setLayout(form)
self.setWindowTitle('QFormLayout')
self.show() if __name__ == '__main__':
app = QApplication(sys.argv)
w = Window()
sys.exit(app.exec_())

3.7 嵌套布局

所谓嵌套布局就是综合应用上述的布局进行嵌套以完成整体窗口的布局。下面是有关嵌套布局的两个等价实例。注意第二个实例更加简单。

#!/usr/bin/env python3
# -*- coding: utf-8 -*- import sys
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QVBoxLayout, \
QGridLayout, QFormLayout, QPushButton class Window(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('嵌套布局') # 全局布局:水平
wlayout = QHBoxLayout()
# 局部布局:水平,垂直,网格,表单
hlayout = QHBoxLayout()
vlayout = QVBoxLayout()
glayout = QGridLayout()
flayout = QFormLayout() # 为局部布局添加控件
hlayout.addWidget(QPushButton(str(1)))
hlayout.addWidget(QPushButton(str(2)))
vlayout.addWidget(QPushButton(str(3)))
vlayout.addWidget(QPushButton(str(4)))
glayout.addWidget(QPushButton(str(5)), 0, 0)
glayout.addWidget(QPushButton(str(6)), 0, 1)
glayout.addWidget(QPushButton(str(7)), 1, 0)
glayout.addWidget(QPushButton(str(8)), 1, 1)
flayout.addWidget(QPushButton(str(9)))
flayout.addWidget(QPushButton(str(10)))
flayout.addWidget(QPushButton(str(11)))
flayout.addWidget(QPushButton(str(12))) # 准备4个控件
hwg = QWidget()
vwg = QWidget()
gwg = QWidget()
fwg = QWidget() # 使用4个控件设置局部布局
hwg.setLayout(hlayout)
vwg.setLayout(vlayout)
gwg.setLayout(glayout)
fwg.setLayout(flayout) # 将4个控件添加到全局布局中
wlayout.addWidget(hwg)
wlayout.addWidget(vwg)
wlayout.addWidget(gwg)
wlayout.addWidget(fwg) self.setLayout(wlayout)
self.show() if __name__ == '__main__':
app = QApplication(sys.argv)
w = Window()
sys.exit(app.exec_())

#!/usr/bin/env python3

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QVBoxLayout, \
QGridLayout, QFormLayout, QPushButton class Window(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('嵌套布局')
self.resize(700, 200) # 全局控件(注意参数self),用于承载全局布局
wwg = QWidget(self) # 全局布局
wl = QHBoxLayout(wwg)
hlayout = QHBoxLayout()
vlayout = QVBoxLayout()
glayout = QGridLayout()
flayout = QFormLayout() # 为局部布局添加控件
hlayout.addWidget(QPushButton(str(1)))
hlayout.addWidget(QPushButton(str(2)))
vlayout.addWidget(QPushButton(str(3)))
vlayout.addWidget(QPushButton(str(4)))
glayout.addWidget(QPushButton(str(5)), 0, 0)
glayout.addWidget(QPushButton(str(6)), 0, 1)
glayout.addWidget(QPushButton(str(7)), 1, 0)
glayout.addWidget(QPushButton(str(8)), 1, 1)
flayout.addWidget(QPushButton(str(9)))
flayout.addWidget(QPushButton(str(10)))
flayout.addWidget(QPushButton(str(11)))
flayout.addWidget(QPushButton(str(12))) # 在布局布局wl中添加局部布局
wl.addLayout(hlayout)
wl.addLayout(vlayout)
wl.addLayout(glayout)
wl.addLayout(flayout) self.show() if __name__ == '__main__':
app = QApplication(sys.argv)
w = Window()
sys.exit(app.exec_())

3.8 布局管理器QSplitter

PyQt提供了一个特殊的布局管理器QSplitter,它可以动态地拖动子控件之间的边界,算是一个动态的布局管理器。

与QSplitter相关的方法及其描述如下。

方法 描述
addWidget() 将控件添加到QSplitter管理器的布局中
indexOf() 返回控件在QSplitter管理器中的索引
insertWidget() 根据索引将一个控件插入到QSplitter管理器中
setOrientation() 设置布局方法
Qt.Horizontal:水平方向
Qt.Vertical:垂直方向
setSizes() 设置控件的初始化大小
count() 返回小控件在QSplitter管理器中的数量
#!/usr/bin/env python3

import sys
from PyQt5.QtWidgets import QWidget, QHBoxLayout, QSplitter, QTextEdit, \
QApplication, QFrame
from PyQt5.QtCore import Qt class Window(QWidget):
def __init__(self):
super().__init__()
self.initUI() def initUI(self):
hbox = QHBoxLayout(self)
self.setWindowTitle('QSplitter')
self.setGeometry(300, 300, 300, 200) topleft = QFrame()
topleft.setFrameShape(QFrame.StyledPanel) bottom = QFrame()
bottom.setFrameShape(QFrame.StyledPanel) sp1 = QSplitter(Qt.Horizontal)
te = QTextEdit()
sp1.addWidget(topleft)
sp1.addWidget(te)
sp1.setSizes([100, 200]) sp2 = QSplitter(Qt.Vertical)
sp2.addWidget(sp1)
sp2.addWidget(bottom) hbox.addWidget(sp2)
self.setLayout(hbox)
self.show() if __name__ == '__main__':
app = QApplication(sys.argv)
w = Window()
sys.exit(app.exec_())

PyQt5之布局管理的更多相关文章

  1. PyQt5教程——布局管理(4)

    PyQt5中的布局管理 布局管理是GUI编程中的一个重要方面.布局管理是一种如何在应用窗口上防止组件的一种方法.我们可以通过两种基础方式来管理布局.我们可以使用绝对定位和布局类. 绝对定位 程序指定了 ...

  2. PyQT5基础布局管理

    绝对定位布局 使用move(x, y)可以对窗口进行布局,以窗口左上角为原点,向右为 x 轴正方向,向下为 y 轴正方向,移动(x,y); import sys from PyQt5.QtGui im ...

  3. PyQt5——布局管理

    PyQt5布局管理使用方法详见:https://blog.csdn.net/jia666666/article/list/3?t=1& PyQt5布局管理汇总: 1.QHBoxLayout 2 ...

  4. 四、PyQt5布局管理(绝对&相对、水平、垂直、格栅、表单)

    目录 一.绝对布局 二.盒布局 三.格栅布局 四.格栅布局跨行跨列显示 布局管理即设置窗体上各个控件的位置,对于新手来说,这是学习的难点. 布局管理根据绝对坐标是否变动分为绝对布局和相对布局两大类.采 ...

  5. PyQT5速成教程-3 布局管理

    本文由 沈庆阳 所有,转载请与作者取得联系! 布局(Layout)管理 Qt Designer中,在工具箱中最上方可以看到有4种布局.分别是垂直布局.水平布局.栅格布局和表单布局.   四种布局 布局 ...

  6. PyQt5(2)——调整布局(布局管理器)第一个程序

    我们拖拽一个UI文件,转为PY文件后生成一个类Ui_MainWindow 此时,我们新建一个文件,用来控制业务逻辑(继承界面中的类),跟界面分开,这样我们就完成了界面和逻辑相分离(这段代码使用率基本1 ...

  7. PyQt5笔记之布局管理

    代码:界面与逻辑分离 这是使用Designer做出的GUI,然后通过转换得到的Py代码.(界面文件) # -*- coding: utf-8 -*- # Form implementation gen ...

  8. PyQt5布局管理器

    布局分类 绝对定位:使用move方法将空间直接定死在某个坐标,不会随着窗口大小的改变而改变 可变布局:使用各种布局管理器,实现组件的位置和大小随着窗口的变化而变化 布局管理器 QHBoxLayout: ...

  9. PyQt5布局管理(1)

    Qt布局管理按简单分可分为绝对位置布局和布局管理器布局 一.绝对位置布局: 组件不放在布局管理器中,通过函数setGeometry(x,y,width,height)来设定组件相对其父窗口的位置.其中 ...

随机推荐

  1. 【Teradata】安装SQL Assistant和Administrator 16.20(含查看.net版本)

    1.安装介质获取: 获取的路径:connections==>Gateways==>Customer Services==>TOOLS & APPLICATIONS(点击Mor ...

  2. R语言学习——数据框

    > #数据框可以包含不同模式(数值型.字符型.逻辑型等)的数据,是R中最常处理的数据结构.数据框可以通过函数data.frame()创建:mydata<-data.frame(coll,c ...

  3. 文本分类实战(二)—— textCNN 模型

    1 大纲概述 文本分类这个系列将会有十篇左右,包括基于word2vec预训练的文本分类,与及基于最新的预训练模型(ELMo,BERT等)的文本分类.总共有以下系列: word2vec预训练词向量 te ...

  4. KindEditor富文本编辑器使用

    我的博客本来打算使用layui的富文本编辑器,但是出了一个问题,无法获取编辑器内容,我参考官方文档,获取内容也就那几个方法而已,但是引入进去后始终获取的值为空,百度和bing都试过了,但是始终还是获取 ...

  5. 【P2015】二叉苹果树 (树形DP分组背包)

    题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 现在这颗树枝条太多了,需要剪枝.但是 ...

  6. JavaWeb工程中web.xml基本配置(转载学习)

    一.理论准备 先说下我记得xml规则,必须有且只有一个根节点,大小写敏感,标签不嵌套,必须配对. web.xml是不是必须的呢?不是的,只要你不用到里面的配置信息就好了,不过在大型web工程下使用该文 ...

  7. Golang 入门 : 字符串

    在 Golang 中,字符串是一种基本类型,这一点和 C 语言不同.C 语言没有原生的字符串类型,而是使用字符数组来表示字符串,并以字符指针来传递字符串.Golang 中的字符串是一个不可改变的 UT ...

  8. C#中字节数组(byte[])和字符串相互转换

    转换过程主要使用到System.Text.Encoding命名空间下的类 1. 字符串转换成字节数组byte[]: string str = "This is test string&quo ...

  9. TypeError: sequence item 1: expected str instance, int found

    Error Msg Traceback (most recent call last): File "E:/code/adva_code/my_orm.py", line 108, ...

  10. Openstack基础环境交换机常用配置(CISCO 3750G为例)

    NOTE: 用户模式提示符为:cisco> 特权模式提示符为:cisco# 全局配置模式提示符为:cisco(config)# 端口模式提示符为:cisco(config-if)# 基础操作   ...