- pyqt5 学习笔记四 (QBoxLayout) 垂直布局器与水平布局器
- 布局器
- (一)类的写法
- 1、类的写法
- 2、快捷键 ctrl
- (二)垂直布局窗口 QVBoxLayout
- 1、垂直布局器的初步写法
- 2、layout.addStretch() 伸缩器“弹簧”
- (1) addStretch() 没有设置值
- (2) addStretch(1) 设置值
- (3) addStretch() 有的设置值;有的不设置
- (三)水平布局窗口 QHBoxLayout
- 1、QGroupBox
- (1) 错误写法
- (2) 正确写法1
- (2) 正确写法2
- 2、水平布局与垂直布局的混合使用
布局器写在前面:
①本教程使用pycharm编译器进行pyqt5的学习,安装教程请大家自行百度
②本系列博客根据B站王铭东博主教程学习 学习代码 笔记4
链接:https://pan.baidu.com/s/1i3y4mI_9N84iAC6tav-j8Q
提取码:gupx
资料:
【1】B站教程
【2】B站教程配套课件
【3】PyQt官网的所有模块 (有部分内容没有补充进去)
【4】C++具体实现的API文档
共有四种:
QBoxLayout:垂直水平布局器
QGridLayout:网格布局器
QFormLayout:暂未更新
QStackedLayout:暂未更新
本次代码引入类的概念,类的含义参考链接:https://blog.csdn.net/m0_54162026/article/details/113184990
import sys
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget, QPushButton, QGroupBox, QMainWindow
from PyQt5.QtCore import Qt
class MyWindow(QWidget):
# 重写init方法
def __init__(self):
# 切记一定要调用父类的__init__方法,因为它里面有很多对UI空间的初始化操作
super().__init__()
if __name__ == '__main__':
app = QApplication(sys.argv)
# 创建一个QWidget子类
w = MyWindow()
w.show()
app.exec()
① QApplication(sys.argv)
② class MyWindow(QWidget):新建一个类,继承QWidget (ps:Object类为所有类的父类)
③ def init(self): super().__init__() 一定要调用父类的__init__方法,因为它里面有很多对UI空间的初始化操作(PS:python的深度学习很多模型的类也是要调用父类的init方法的)
如果不写调用父类的方法会报错:RuntimeError: super-class __init__() of type MyWindow was never called
④ w = MyWindow():
⑤ 类的实例化,生成一个w对象
⑥ w.show() app.exec()
ctrl+左键:快速跳转,如:想要查看QWidget类的代码,鼠标指向QWidget,同时按ctrl并点击QWidget
跳转到此处:
layout = QVBoxLayout() :创建垂直布局器
layout.addWidget(btn1) :将控件添加到布局器中
self.setLayout(layout) :让当前窗口使用layout布局器
代码:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton
# 创建MyWindow,继承了QWidget父类
class MyWindow(QWidget):
# 重写init方法
def __init__(self):
# 切记一定要调用父类的__init__方法,因为它里面有很多对UI空间的初始化操作
super().__init__()
self.resize(300,300)
self.setWindowTitle("垂直布局")
# 创建垂直布局器
layout = QVBoxLayout()
# 生成按钮
btn1 = QPushButton("按钮1")
btn2 = QPushButton("按钮2")
btn3 = QPushButton("按钮3")
# 按钮添加到布局器中(有布局器直接放到布局器中)
layout.addWidget(btn1)
layout.addWidget(btn2)
layout.addWidget(btn3)
# 让当前窗口使用设置好的layout布局
self.setLayout(layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyWindow()
w.show()
app.exec()
输出结果:
layout.addStretch() :可伸缩的间隔,在垂直布局下就是垂直方向的控件之间的间隔。作用是在布局器中增加一个伸缩量,里面的参数表示QSpacerItem的个数,默认值为零
(1) addStretch() 没有设置值代码:
import sys
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget, QPushButton, QGroupBox, QMainWindow
from PyQt5.QtCore import Qt
class MyWindow(QWidget):
def __init__(self):
# 切记一定要调用父类的__init__方法,因为它里面有很多对UI空间的初始化操作
super().__init__()
self.resize(300, 300)
self.setWindowTitle("垂直布局")
# 垂直布局
layout = QVBoxLayout()
# 按钮1
btn1 = QPushButton("按钮1")
# 添加到布局器中
# layout.addWidget(btn1, Qt.AlignmentFlag.AlignTop)
layout.addWidget(btn1)
layout.addStretch()
# 按钮2
btn2 = QPushButton("按钮2")
layout.addWidget(btn2)
layout.addStretch()
# 按钮3
btn3 = QPushButton("按钮3")
layout.addWidget(btn3)
layout.addStretch()
self.setLayout(layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyWindow()
w.show()
app.exec()
输出结果:
如果函数layout.addStretch() 没有参数,则按照“弹簧”的个数,将间隔等分,a=b=c,如上图所示。
代码:
# 垂直布局
layout = QVBoxLayout()
layout.addStretch(1)
# 按钮1
btn1 = QPushButton("按钮1")
layout.addWidget(btn1)
layout.addStretch(1)
# 按钮2
btn2 = QPushButton("按钮2")
layout.addWidget(btn2)
layout.addStretch(1)
# 按钮3
btn3 = QPushButton("按钮3")
layout.addWidget(btn3)
layout.addStretch(2)
self.setLayout(layout)
输出结果:
按照设定的值将间隔按照比例分为1:1:1:2
layout = QVBoxLayout()
layout.addStretch(1)
# 按钮1
btn1 = QPushButton("按钮1")
layout.addWidget(btn1)
layout.addStretch(1)
# 按钮2
btn2 = QPushButton("按钮2")
layout.addWidget(btn2)
layout.addStretch(1)
# 按钮3
btn3 = QPushButton("按钮3")
layout.addWidget(btn3)
layout.addStretch()
输出结果: 1:1:1:0 不设置值的没有分配
QGroupBox必须使用布局才能正确显示,否则会挤在一起
(1) 错误写法import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QGroupBox, QRadioButton
class MyWindow(QWidget):
def __init__(self):
super().__init__()
self.initui()
def initui(self):
container = QVBoxLayout()
h_box = QGroupBox("hobby")
QRadioButton("sing",h_box)
QRadioButton("dance",h_box)
QRadioButton("rap",h_box)
container.addWidget(h_box)
self.setLayout(container)
if __name__== '__main__':
app = QApplication(sys.argv)
w = MyWindow()
w.show()
app.exec()
输出结果:
# QGroupBox
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QGroupBox, QRadioButton
if __name__== '__main__':
app = QApplication(sys.argv)
w = QWidget()
container = QVBoxLayout()
v_layout = QVBoxLayout()
h_box = QGroupBox("hobby")
btn1 = QRadioButton("sing")
btn2 = QRadioButton("dance")
btn3 = QRadioButton("rap")
v_layout.addWidget(btn1)
v_layout.addWidget(btn2)
v_layout.addWidget(btn3)
h_box.setLayout(v_layout)
container.addWidget(h_box)
w.setLayout(container)
w.show()
app.exec()
(2) 正确写法2
代码:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QGroupBox, QRadioButton,QHBoxLayout
class MyWindow(QWidget):
def __init__(self):
super().__init__()
self.initui()
def initui(self):
# container = QVBoxLayout()
h_box = QGroupBox("hobby")
v_layout = QVBoxLayout()
btn1 = QRadioButton("sing")
btn2 = QRadioButton("dance")
btn3 = QRadioButton("rap")
v_layout.addWidget(btn1)
v_layout.addWidget(btn2)
v_layout.addWidget(btn3)
h_box.setLayout(v_layout)
h_box.setParent(self)
# container.addWidget(h_box)
# self.setLayout(container)
if __name__== '__main__':
app = QApplication(sys.argv)
w = MyWindow()
w.resize(100,100)
w.show()
app.exec()
输出结果:
QGroupBox步骤:
必须使用布局,将选项添加到布局当中
① h_box = QGroupBox("hobby") :新建group对象
② v_layout = QVBoxLayout() :新建布局
③ btn1 = QRadioButton("sing") :新建group组中的按钮
④ v_layout.addWidget(btn1) :将一系列按钮放入布局中
⑤ h_box.setLayout(v_layout):group使用该布局
此时的group已经设置好了内部的按钮以及按钮的布局,就可以把这个整体作为一个控件使用了
代码:
import sys
from PyQt5.QtWidgets import QWidget, QGroupBox, QRadioButton, QApplication, QVBoxLayout, QHBoxLayout
class MyWindow(QWidget):
def __init__(self):
super().__init__()
self.initui()
def initui(self):
container = QVBoxLayout() # 设置整体垂直布局
# hobby_group
h_group = QGroupBox("hobby")
v_layout = QVBoxLayout() # hobby的选项的垂直布局
btn1 = QRadioButton("sing")
btn2 = QRadioButton("dance")
btn3 = QRadioButton("rap")
v_layout.addWidget(btn1)
v_layout.addWidget(btn2)
v_layout.addWidget(btn3)
h_group.setLayout(v_layout)
# gender_group
g_group = QGroupBox("gender")
h_layout = QHBoxLayout() # gender的选项的水平布局
btn1 = QRadioButton("male")
btn2= QRadioButton("female")
h_layout.addWidget(btn1)
h_layout.addWidget(btn2)
g_group.setLayout(h_layout)
container.addWidget(h_group)
container.addWidget(g_group)
self.setLayout(container) # 有且只有一个self.layout
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyWindow()
w.show()
app.exec()
结果显示:
(1) 设置垂直布局container (2) hobby组: ① 创建hobby的group 和 组里面的button ② 新建hobby的布局layout1 ③ 将hobby的按钮放入hobby布局中 ④ 对hobby组使用layout1布局 (3) gender组: ① 创建gender的group 和 组里面的button ② 新建gender的布局layout2 ③ 将gender的按钮放入gender布局中 ④ 对gender组使用layout2布局 (4) 将hobby组与gender组放入整体的窗口布局container中



