2.2 布局管理
《零基础入门玩转 PyQt5》 邀请码: LWskm3AS
布局就是如何管理应用中的元素和窗口,有两种方式可以搞定:绝对定位和layout类
2.2.1 绝对定位
每个程序都是以像素为单位区分元素的位置,衡量元素的大小。所以我们完全可以使用绝对定位搞定每个元素和窗口的位置。但是这也有局限性:
- 元素不会随着窗口的位置和大小变化而变化
- 不能适用于不同的平台和不同分辨率的显示器
- 更改应用字体大小会破坏布局
- 如果重构这个应用,需要计算每个元素的位置和大小
程序展示
本例中,用绝对定位布局应用
import sys
from PyQt5.QtWidgets import QWidget, QApplication, QLabel
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
lab1 = QLabel("Hello world", self)
lab1.move(20, 20)
lab2 = QLabel("人生苦短", self)
lab2.move(40, 40)
lab3 = QLabel("我用Python", self)
lab3.move(60, 60)
self.setGeometry(300, 300, 250, 150)
self.setWindowTitle('绝对定位')
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
e = Example()
sys.exit(app.exec_())
程序预览:
代码解释
move()
:给元素定位,使用x、y坐标,x、y坐标的原点是程序的左上角
lab1 = QLabel("Hello world", self)
lab1.move(20, 20)
2.2.2 盒子布局
使用盒布局能让程序具有更强的适应性,QHBoxLayout
和QVBoxLayout
是基本的布局类,分别是水平布局和垂直布局
如果我们需要把两个按钮放在程序的右下角,创建这样的布局,只需要一个水平布局加一个垂直布局的盒子,再用弹性布局增加一点间隙就可以了
程序展示
本例中,用盒子布局布局应用。当改变窗口大小的时候,它们能依然保持在相对的位置
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QHBoxLayout, QVBoxLayout
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
ok = QPushButton("OK")
cancle = QPushButton("cancle")
# 水平布局
hbox = QHBoxLayout()
hbox.addStretch(1)
hbox.addWidget(ok)
hbox.addWidget(cancle)
# 垂直布局
vbox = QVBoxLayout()
vbox.addStretch(1)
vbox.addLayout(hbox)
self.setLayout(vbox)
self.setGeometry(300, 300, 300, 150)
self.setWindowTitle('盒子布局')
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
e = Example()
sys.exit(app.exec_())
程序预览:
代码解释
创建两个按钮
ok = QPushButton("OK")
cancle = QPushButton("cancle")
创建水平布局对象,stretch
函数的作用是在两个按钮前面增加弹性空间,它会将按钮挤到窗口的右边
# 水平布局
hbox = QHBoxLayout()
hbox.addStretch(1)
hbox.addWidget(ok)
hbox.addWidget(cancle)
为布局的需要,我们把这个水平布局放到垂直布局盒里面,弹性元素会把水平布局挤到窗口的下边
# 垂直布局
vbox = QVBoxLayout()
vbox.addStretch(1)
vbox.addLayout(hbox)
最后,把布局在设置到窗口中
self.setLayout(vbox)
2.2.3 栅格布局
最常用的还是栅格布局了,这种布局是把窗口分为行和列。创建和使用栅格布局,需要使用QGridLayout模块。
程序展示
本例中,创建栅格化的按钮
import sys
from PyQt5.QtWidgets import QWidget, QApplication, QGridLayout, QPushButton
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
names = [
'cls', 'back', '<-', '=',
'9', '8', '7', '+',
'6', '5', '4', '-',
'3', '2', '1', '*',
'sin', '0', '.', '/'
]
positions = [(i, j) for i in range(5) for j in range(4)]
g = QGridLayout()
for name, position in zip(names, positions):
b = QPushButton(name)
g.addWidget(b, *position)
self.setLayout(g)
self.move(300, 150)
self.setWindowTitle('Calculator')
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
e = Example()
sys.exit(app.exec_())
程序预览:
代码解释
创建一个QGridLayout实例
g = QGridLayout()
这是将要使用的按钮名称
names = [
'cls', 'back', '<-', '=',
'9', '8', '7', '+',
'6', '5', '4', '-',
'3', '2', '1', '*',
'sin', '0', '.', '/'
]
创建按钮位置列表
positions = [(i,j) for i in range(5) for j in range(4)]
创建按钮,并使用addWidget()
方法把按钮放到布局里面
for name, position in zip(names, positions):
b = QPushButton(name)
g.addWidget(b, *position)
把栅格布局放到程序窗口里
self.setLayout(grid)
2.2.4 栅格布局案例
制作提交反馈信息的布局
程序展示
本例中,创建一个有三个标签的窗口。两个行编辑和一个文版编辑,这是用QGridLayout
模块搞定的
import sys
from PyQt5.QtWidgets import QWidget, QGridLayout, QApplication, QLabel, QLineEdit, QTextEdit
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
title = QLabel('title')
author = QLabel('author')
review = QLabel('review')
dtitle = QLineEdit()
dauthor = QLineEdit()
dreview = QTextEdit()
g = QGridLayout()
g.setSpacing(15)
g.addWidget(title, 0, 0)
g.addWidget(author, 1, 0)
g.addWidget(review, 2, 0)
g.addWidget(dtitle, 0, 1)
g.addWidget(dauthor, 1, 1)
g.addWidget(dreview, 2, 1, 5, 1)
self.setLayout(g)
self.setGeometry(300, 300, 350, 300)
self.setWindowTitle('Review')
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
x = Example()
sys.exit(app.exec_())
程序预览:
代码解释
创建三个标签控件
title = QLabel('title')
author = QLabel('author')
review = QLabel('review')
创建文本编辑框
dtitle = QLineEdit()
dauthor = QLineEdit()
dreview = QTextEdit()
在控件之间设置15个空格
g.setSpacing(15)
指定组件的跨行和跨列的大小,这里指定这个元素跨5行显示
g.addWidget(reviewEdit, 3, 1, 5, 1)