Python桌面开发pyqt5—布局

QBoxLayout

流程

label = QLabel('标签')
label_1 = QLabel('标签1')
label_2 = QLabel('标签2')
label_3 = QLabel('标签3')
label_4 = QLabel('标签4')
label_5 = QLabel('标签5')
label_6 = QLabel('标签6')
label.setStyleSheet('background-color:red;')
label_1.setStyleSheet('background-color:green;')
label_2.setStyleSheet('background-color:blue;')
label_3.setStyleSheet('background-color:yellow;')
label_4.setStyleSheet('background-color:pink;')
label_5.setStyleSheet('background-color:orange;')
label_6.setStyleSheet('background-color:cyan;')

layout = QBoxLayout(QBoxLayout.TopToBottom)
self.setLayout(layout)

# 设置内间距
layout.setSpacing(50)
# 设置外间距
layout.setContentsMargins(11, 20, 30, 40)
print(layout.contentsMargins().left())  # 获取某一边间距

# 替换控件
layout.replaceWidget(label, label_3)
label.hide()  # 被替换的控件必须被隐藏或删除引用
label.setParent(None)
label.destroyed.connect(lambda: print('label_1被销毁!'))

# 布局的嵌套:设置子布局
h_layout = QBoxLayout(QBoxLayout.LeftToRight)
h_layout.addWidget(label_4)
h_layout.addWidget(label_5)
h_layout.addWidget(label_6)
# 最终添加子布局
layout.addWidget(label_3)
layout.addWidget(label_1)
layout.addLayout(h_layout)  # 子布局放在label_1和label_2之间
layout.addWidget(label_2)

# 设置布局是否生效
layout.setEnabled(True)  # 默认为True

在这里插入图片描述

布局方向

# 案例:每隔1s改变布局方向
label = QLabel('标签')
label_1 = QLabel('标签1')
label_2 = QLabel('标签2')
label.setStyleSheet('background-color:red;')
label_1.setStyleSheet('background-color:green;')
label_2.setStyleSheet('background-color:blue;')

layout = QBoxLayout(QBoxLayout.TopToBottom)
layout.addWidget(label)
layout.addWidget(label_1)
layout.addWidget(label_2)
self.setLayout(layout)

timer = QTimer(self)
def func():
    layout.setDirection((layout.direction() + 1) % 4)  # 改变布局方向
timer.timeout.connect(func)
timer.start(1000)

在这里插入图片描述

添加元素

label = QLabel('标签')
label_1 = QLabel('标签1')
label_2 = QLabel('标签2')
label_3 = QLabel('标签3')
label.setStyleSheet('background-color:red;')
label_1.setStyleSheet('background-color:green;')
label_2.setStyleSheet('background-color:blue;')
label_3.setStyleSheet('background-color:yellow;')

layout = QBoxLayout(QBoxLayout.TopToBottom)
layout.addWidget(label)
layout.addSpacing(80)  # 添加空白盒子
layout.addWidget(label_1)
layout.addWidget(label_2)
self.setLayout(layout)

# 插入元素
layout.insertWidget(1, label_3)  # 在索引为1处插入label_3

# 插入布局(略)
# layout.insertLayout(布局)

# 移除元素
layout.removeWidget(label_3)
label_3.setParent(None)  # 必须还要清除或者隐藏(hide -》 show显示)

# 指定索引插入空白盒子
layout.insertSpacing(4, 80)  # 索引不包括空白

在这里插入图片描述

伸缩因子

label = QLabel('标签')
label_1 = QLabel('标签1')
label_2 = QLabel('标签2')
label_3 = QLabel('标签3')
label.setStyleSheet('background-color:red;')
label_1.setStyleSheet('background-color:green;')
label_2.setStyleSheet('background-color:blue;')
label_3.setStyleSheet('background-color:yellow;')

# 添加伸缩因子
layout = QBoxLayout(QBoxLayout.TopToBottom)
layout.addWidget(label)  # 可以传入第二个可选参数,即为伸缩因子的比例
layout.addStretch()  # 添加弹簧
layout.addWidget(label_1)
layout.addStretch()  # 添加弹簧
layout.addWidget(label_2)
self.setLayout(layout)

# 修改伸缩因子
layout.setStretchFactor(label_2, 1)  # 设置为1,空白全占据

在这里插入图片描述

水平布局

label = QLabel('标签')
label_1 = QLabel('标签1')
label_2 = QLabel('标签2')
label.setStyleSheet('background-color:red;')
label_1.setStyleSheet('background-color:green;')
label_2.setStyleSheet('background-color:blue;')

# 设置水平布局
h_layout = QHBoxLayout()
h_layout.addWidget(label)
h_layout.addWidget(label_1)
h_layout.addWidget(label_2)
self.setLayout(h_layout)

# 调用父类的方法修改方向
h_layout.setDirection(QBoxLayout.RightToLeft)

在这里插入图片描述

QFormLayout

流程

label_name = QLabel('姓名:')
label_sex = QLabel('性别')
le_name = QLineEdit()
sb_age = QSpinBox()
m_rb = QRadioButton('男')
f_rb = QRadioButton('女')
lyt_sex = QHBoxLayout()
lyt_sex.addWidget(m_rb)
lyt_sex.addWidget(f_rb)
submit_btn = QPushButton('提交')

# 创建布局
fl = QFormLayout()
# 把布局管理器赋值给需要布局的父控件
self.setLayout(fl)
# 把需要布局的子控件交给布局管理器布局
fl.addRow(label_name,le_name)
fl.addRow('年龄(&a):',sb_age)		# 可不写标签组件直接写汉字,可关联快捷键,还可添加小伙伴
fl.addRow(label_sex,lyt_sex)
# 在指定索引插入行
fl.insertRow(-1,submit_btn)		# 注意,若索引越界,则自动按顺序添加在最后

# 获取行信息
print(fl.rowCount())  # 获取行数
print(fl.getWidgetPosition(label_sex))  # 获取控件信息。参数1为位置,参数2为枚举值
print(fl.getLayoutPosition(fl))  # 获取子布局的位置。若返回-1,代表没找到

在这里插入图片描述

插入移除行

label_name = QLabel('姓名:')
label_age = QLabel('年龄:')
label_sex = QLabel('性别')
le_name = QLineEdit()
sb_age = QSpinBox()
m_rb = QRadioButton('男')
f_rb = QRadioButton('女')
lyt_sex = QHBoxLayout()
lyt_sex.addWidget(m_rb)
lyt_sex.addWidget(f_rb)
submit_btn = QPushButton('提交')

fl = QFormLayout()
self.setLayout(fl)

# 插入行
fl.setWidget(0, QFormLayout.LabelRole, label_name)
fl.addRow(label_age)  # 如果索引1处某元素占据了一行
fl.setWidget(1, QFormLayout.FieldRole, label_sex)  # 那么添加行只能在此索引的左侧添加,不能在右边
fl.setWidget(2, QFormLayout.SpanningRole, submit_btn)

# 移除一整行行(删除子控件)
fl.removeRow(2)  # 会删除一行所有的内容
# 移除控件。
fl.removeWidget(label_name)

''''#移除行(不删除子控件)
print(fl.takeRow(0).labelItem.widget())
print(fl.takeRow(0).fieldItem)
#必须彻底删除子控件
label_name.setParent(None)
label_age.setParent(None)'''

在这里插入图片描述

标签与行策略

label_name = QLabel('===' * 30)
le_name = QLineEdit()

fl = QFormLayout()
self.setLayout(fl)
fl.addRow(label_name, le_name)

# 修改标签信息
# fl.labelForField(label_name).setText('name')

# 修改行策略
fl.setRowWrapPolicy(QFormLayout.WrapAllRows)  # 设置都为上下结构,标签在上,输入框在下

在这里插入图片描述

对齐方式和间距

label_name = QLabel('==' * 10)
label_age = QLabel('年龄:')
le_name = QLineEdit()
sb_age = QSpinBox()

fl = QFormLayout()
self.setLayout(fl)

fl.addRow(label_name, le_name)
fl.addRow(label_age, sb_age)

# 修改表单对齐方式
fl.setFormAlignment(Qt.AlignLeft | Qt.AlignVCenter)  # 靠左竖直居中
# 获取表单对齐方式
print(fl.formAlignment())

# 修改标签对齐方式
fl.setLabelAlignment(Qt.AlignCenter)  # 标签居中

# 设置垂直间距
fl.setVerticalSpacing(30)
# 设置水平间距
fl.setHorizontalSpacing(30)

在这里插入图片描述

QGridLayout

流程

self.label = QLabel('标签')
self.label_1 = QLabel('标签1')
self.label_2 = QLabel('标签2')
self.label.setStyleSheet('background-color:red;')
self.label_1.setStyleSheet('background-color:green;')
self.label_2.setStyleSheet('background-color:blue;')

gl = QGridLayout()
self.setLayout(gl)

# 添加组件
gl.addWidget(self.label)
gl.addWidget(self.label_1, 0, 1)
gl.addWidget(self.label_2, 1, 0, 1, 2)

# 获取位置
print(gl.getItemPosition(2))

在这里插入图片描述

最小列宽行高与拉伸系数

self.label = QLabel('标签')
self.label_1 = QLabel('标签1')
self.label_2 = QLabel('标签2')
self.label.setStyleSheet('background-color:red;')
self.label_1.setStyleSheet('background-color:green;')
self.label_2.setStyleSheet('background-color:blue;')

gl = QGridLayout()
self.setLayout(gl)

gl.addWidget(self.label)
gl.addWidget(self.label_1, 0, 1)
gl.addWidget(self.label_2, 1, 0, 1, 2)

# 设置最小宽度限制
gl.setColumnMinimumWidth(0, 100)
# 最小行高
gl.setRowMinimumHeight(0, 100)

# 垂直拉伸系数:默认所有拉伸系数都是0.可在addWidget传入拉伸系数
gl.setColumnStretch(0, 2)
gl.setColumnStretch(1, 1)  # 第0列和第1列占比2:1
# 水平拉伸系数
gl.setRowStretch(1, 1)  # 占的份额最大,空白区域全都给他

在这里插入图片描述

行列数与间距

self.label = QLabel('标签')
self.label_1 = QLabel('标签1')
self.label_2 = QLabel('标签2')
self.label.setStyleSheet('background-color:red;')
self.label_1.setStyleSheet('background-color:green;')
self.label_2.setStyleSheet('background-color:blue;')

gl = QGridLayout()
self.setLayout(gl)

gl.addWidget(self.label)
gl.addWidget(self.label_1, 0, 1)
gl.addWidget(self.label_2, 1, 0, 1, 2)

# 获取间距
print(gl.spacing())  # 间距,默认为7
print(gl.horizontalSpacing())  # 水平间距
print(gl.verticalSpacing())  # 垂直间距

# 设置间距
gl.setVerticalSpacing(20)  # 设置垂直间距
gl.setHorizontalSpacing(20)  # 设置水平间距
gl.setSpacing(20)  # 设置间距(与上面两个等效),设置的水平和垂直间距必须相等

# 获取数量
print(gl.rowCount())  # 共有多少行
print(gl.columnCount())  # 共有多少列

# 获取某行某列的信息
print(gl.cellRect(0, 1))  # 由于版本原因,这个方法必须在主窗口显示之后才能起作用

QStackedLayout

流程

# 创建一个布局管理对象
sl = QStackedLayout()

# 把布局对象设置给需要布局的父对象(这一步一定不能和第3步颠倒)
self.setLayout(sl)

# 通过布局对象,管理布局子控件
label = QLabel('标签')
label_1 = QLabel('标签1')
label_2 = QLabel('标签2')
label_3 = QLabel('标签3')
label_4 = QLabel('标签4')
label_5 = QLabel('标签5')
label_6 = QLabel('标签6')
label.setStyleSheet('background-color:red;')
label_1.setStyleSheet('background-color:green;')
label_2.setStyleSheet('background-color:blue;')
label_3.setStyleSheet('background-color:yellow;')
label_4.setStyleSheet('background-color:pink;')
label_5.setStyleSheet('background-color:orange;')
label_6.setStyleSheet('background-color:cyan;')

v_layout = QVBoxLayout()
v_layout.addWidget(label_4)
v_layout.addWidget(label_5)
v_layout.addWidget(label_6)

sl.addWidget(label)
sl.addWidget(label_1)
sl.addWidget(label_2)

在这里插入图片描述

简单方法

# 设置当前展示的界面
sl.setCurrentIndex(1)
sl.setCurrentWidget(label1)

# 获取当前展示元素的索引
print(sl.currentIndex())

# 插入标签.如果索引(参数1)越界了,会自动优化处理,设置为最后一个
# 规则:如果插入的索引(参数1)在当前展示的标签前,
# 就将插入的标签的索引置为当前的索引,并将当前元素索引依次后移一位
sl.insertWidget(1, label_3)

# 获取标签的文本
print(sl.widget(2).text())

展示模式

sl = QStackedLayout()
self.setLayout(sl)

label = QLabel('标签')
label_1 = QLabel('标签1')
label_2 = QLabel('标签2')
label.setStyleSheet('background-color:red;')
label_1.setStyleSheet('background-color:green;')
label_2.setStyleSheet('background-color:blue;')
sl.addWidget(label)
sl.addWidget(label_1)
sl.addWidget(label_2)

# 设置展示模式
sl.setStackingMode(QStackedLayout.StackAll)  # 默认是StackAll,只展示一个。

label.setFixedSize(100, 100)
label_1.setFixedSize(200, 200)

在这里插入图片描述

切换和信号

sl = QStackedLayout()
self.setLayout(sl)

label = QLabel('标签')
label_1 = QLabel('标签1')
label_2 = QLabel('标签2')
label.setStyleSheet('background-color:red;')
label_1.setStyleSheet('background-color:green;')
label_2.setStyleSheet('background-color:blue;')
sl.addWidget(label)
sl.addWidget(label_1)
sl.addWidget(label_2)

''''#切换界面展示
sl.setCurrentIndex(1)
sl.setCurrentWidget(label_1)'''

timer = QTimer(self)
timer.timeout.connect(lambda: sl.setCurrentIndex((sl.currentIndex() + 1) % sl.count()))
timer.start(1000)

# 信号:当前展示的窗口改变
sl.currentChanged.connect(lambda calue: print(calue))

尺寸策略

建议最小尺寸

class Label(QLabel):
	def minimumSizeHint(self):
		'''最小的建议尺寸'''
		return QSize(150, 150)

label = QLabel('标签')
label_1 = QLabel('标签1')
label_2 = Label('标签2')
label.setStyleSheet('background-color:red;')
label_1.setStyleSheet('background-color:green;')
label_2.setStyleSheet('background-color:blue;')

layout = QVBoxLayout()
self.setLayout(layout)
layout.addWidget(label)
layout.addWidget(label_1)
layout.addWidget(label_2)

建议尺寸

class MyLabel(QLabel):
	def sizeHint(self):
		'''建议尺寸'''
        return QSize(150, 150)

label = MyLabel('标签')
label_1 = QLabel('标签1')
label_2 = QLabel('标签2')
label.setStyleSheet('background-color:red;')
label_1.setStyleSheet('background-color:green;')
label_2.setStyleSheet('background-color:blue;')

layout = QVBoxLayout()
self.setLayout(layout)
layout.addWidget(label)
layout.addWidget(label_1)
layout.addWidget(label_2)

缩放策略

# 设置缩放策略
"""Preferred	#可伸展也可收缩(默认)
Expanding		#也可伸缩,但是比Prefered优先级更高(当有两个及以上空间的时候油下锅)
Fixed			#固定不变
Minimum			#将建议尺寸作为最小尺寸,可以缩放但不能低于最小
Maximum			#将建议尺寸作为最大尺寸,可以缩放但不能高于最大
Ignored			#忽略SizeHint的作用"""
label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
# 可设置策略对象,再传入
sp = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
sp.setRetainSizeWhenHidden(True)  # 位置必须放在传入策略之前。当某标签隐藏时,保建议留尺寸
label_1.setSizePolicy(sp)

label_1.hide()

# 固定标签的尺寸,直接忽略策略和建议尺寸
label.setFixedSize(300, 100)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值