🌟想系统化学习 GUI 编程?看看这个:[Python GUI 编程] PySide & PyQt - 学习手册-CSDN博客
0x01:PyQT 布局管理器的基本概念
PyQT 的布局管理器(Layout Manager)是用于自动排列和管理窗口中控件(Widgets)位置和大小的工具。它简化了界面的设计,确保控件在不同窗口尺寸或分辨率下保持合理的布局。
当可用空间发生变化时,布局管理器会自动调整内部控件的位置和大小,以适应动态变化的空间。另外,布局管理器并不属于界面控件,不能被展示(换句话说,它不继承自 QWidget),它只是界面控件的 “定位策略”,它只能告诉你如何摆放控件与如何设置每个控件的尺寸大小。
QWidget 的子类及其本身都可以通过 setLayout()
方法使用布局来管理它们的子控件:
0x02:PyQT 布局管理器继承结构图
下面是 PyQT 布局管理器的继承结构图,也是我们后面学习的路径图:
0x03:PyQT 布局管理器的使用流程
PyQT 布局管理器的使用流程如下图所示,其中第 2 点与第 3 点为可选的,笔者会单独拎出来讲解:
0x0301:流程推导 — 创建布局对象
下面这个代码中,我们创建了三个 QLabel 对象,并且为每个 QLabel 都设置了不同的颜色,但是我们并没有说明这三个 QLabel 对象的父对象是谁,所以在展示的时候这三个 QLabel 对象都没展示出来(主要是关注创建布局对象的语句):
import sys
from PyQt5.Qt import *
class MyWindow(QWidget):
def __init__(self):
super().__init__()
self.resize(900, 600)
self.setup_ui()
def setup_ui(self):
# 创建三个 Label 控件
label1 = QLabel()
label1.setStyleSheet("background-color: green;")
label2 = QLabel()
label2.setStyleSheet("background-color: cyan;")
label3 = QLabel()
label3.setStyleSheet("background-color: red;")
# 创建垂直布局管理器
v_layout = QVBoxLayout()
if __name__ == '__main__':
# 1. 创建一个应用程序对象
app = QApplication(sys.argv)
# 2. 控件操作
window = MyWindow()
# 3. 展示控件
window.show()
# 4. 应用程序的执行,进入到消息循环
sys.exit(app.exec_())
0x0302:流程推导 — 将子控件添加到布局管理器中
有了布局对象,我们还得将三个 QLabel 添加到布局管理器中,布局管理器才能管理它们,但从运行结果可以看出来,添加到了布局管理器中还是没用,我们窗口中依旧没有显示三个 Label 标签:
import sys
from PyQt5.Qt import *
class MyWindow(QWidget):
def __init__(self):
super().__init__()
self.resize(900, 600)
self.setup_ui()
def setup_ui(self):
# 创建三个 Label 控件
label1 = QLabel()
label1.setStyleSheet("background-color: green;")
label2 = QLabel()
label2.setStyleSheet("background-color: cyan;")
label3 = QLabel()
label3.setStyleSheet("background-color: red;")
# 创建垂直布局管理器
v_layout = QVBoxLayout()
# 将三个 Label 控件添加到垂直布局管理器中
v_layout.addWidget(label1)
v_layout.addWidget(label2)
v_layout.addWidget(label3)
if __name__ == '__main__':
# 1. 创建一个应用程序对象
app = QApplication(sys.argv)
# 2. 控件操作
window = MyWindow()
# 3. 展示控件
window.show()
# 4. 应用程序的执行,进入到消息循环
sys.exit(app.exec_())
0x0303:流程推导 — 将布局对象设置给父控件
在上一步中,哪怕我们将控件添加进了布局管理器,那也是布局管理器和控件自己玩自己的。而我们想要展示控件,就得依赖于父控件,所以,我们还得将布局管理器设置给一个可以进行展示的父控件上,比如 self
:
import sys
from PyQt5.Qt import *
class MyWindow(QWidget):
def __init__(self):
super().__init__()
self.resize(900, 600)
self.setup_ui()
def setup_ui(self):
# 创建三个 Label 控件
label1 = QLabel()
label1.setStyleSheet("background-color: green;")
label2 = QLabel()
label2.setStyleSheet("background-color: cyan;")
label3 = QLabel()
label3.setStyleSheet("background-color: red;")
# 创建垂直布局管理器
v_layout = QVBoxLayout()
# 将三个 Label 控件添加到垂直布局管理器中
v_layout.addWidget(label1)
v_layout.addWidget(label2)
v_layout.addWidget(label3)
# 将垂直布局管理器设置给窗口
self.setLayout(v_layout)
if __name__ == '__main__':
# 1. 创建一个应用程序对象
app = QApplication(sys.argv)
# 2. 控件操作
window = MyWindow()
# 3. 展示控件
window.show()
# 4. 应用程序的执行,进入到消息循环
sys.exit(app.exec_())
0x0304:扩展流程 — 设置布局对象属性
在上面那个案例中我们已经成功通过布局管理器展示了三个 Label 标签,但是仔细观察可以发现,每个 Label 标签的周围都有一点空白,我想给它去掉或者增加我该怎么办。此时,我们就可以通过设置布局对象的属性来完成这一操作:
import sys
from PyQt5.Qt import *
class MyWindow(QWidget):
def __init__(self):
super().__init__()
self.resize(900, 600)
self.setup_ui()
def setup_ui(self):
# 创建三个 Label 控件
label1 = QLabel()
label1.setStyleSheet("background-color: green;")
label2 = QLabel()
label2.setStyleSheet("background-color: cyan;")
label3 = QLabel()
label3.setStyleSheet("background-color: red;")
# 创建垂直布局管理器
v_layout = QVBoxLayout()
# 设置布局对象属性,
v_layout.setContentsMargins(0, 0, 0, 0) # 设置布局管理器四周的边距
v_layout.setSpacing(0) # 设置控件之间的间距
# 将三个 Label 控件添加到垂直布局管理器中
v_layout.addWidget(label1)
v_layout.addWidget(label2)
v_layout.addWidget(label3)
# 将垂直布局管理器设置给窗口
self.setLayout(v_layout)
if __name__ == '__main__':
# 1. 创建一个应用程序对象
app = QApplication(sys.argv)
# 2. 控件操作
window = MyWindow()
# 3. 展示控件
window.show()
# 4. 应用程序的执行,进入到消息循环
sys.exit(app.exec_())
0x0305:扩展流程 — 调整布局控件的方向
在上面那个例子中,我们展示的是 绿 => 蓝 => 红,我能能不能让其换个方向,改成 红 => 蓝 => 绿 呢?有的兄弟,有的,通过 setLayoutDirection()
方法就可以:
import sys
from PyQt5.Qt import *
class MyWindow(QWidget):
def __init__(self):
super().__init__()
self.resize(900, 600)
self.setup_ui()
def setup_ui(self):
# 创建三个 Label 控件
label1 = QLabel()
label1.setStyleSheet("background-color: green;")
label2 = QLabel()
label2.setStyleSheet("background-color: cyan;")
label3 = QLabel()
label3.setStyleSheet("background-color: red;")
# 创建垂直布局管理器
v_layout = QVBoxLayout()
# 设置布局对象属性,
v_layout.setContentsMargins(0, 0, 0, 0) # 设置布局管理器四周的边距
v_layout.setSpacing(0) # 设置控件之间的间距
# 调整子控件布局方向
v_layout.setDirection(QBoxLayout.BottomToTop) # 从下到上
# 将三个 Label 控件添加到垂直布局管理器中
v_layout.addWidget(label1)
v_layout.addWidget(label2)
v_layout.addWidget(label3)
# 将垂直布局管理器设置给窗口
self.setLayout(v_layout)
if __name__ == '__main__':
# 1. 创建一个应用程序对象
app = QApplication(sys.argv)
# 2. 控件操作
window = MyWindow()
# 3. 展示控件
window.show()
# 4. 应用程序的执行,进入到消息循环
sys.exit(app.exec_())