PyQt5的其他笔记链接:
(5条消息) PyQt5的笔记(上)_我行我素,向往自由的博客-CSDN博客
(5条消息) PyQt5的笔记(中-1)_我行我素,向往自由的博客-CSDN博客
(5条消息) PyQt5的笔记(中-2)_我行我素,向往自由的博客-CSDN博客
(5条消息) PyQt5的笔记(中-3)_我行我素,向往自由的博客-CSDN博客
(5条消息) PyQt5的笔记(中-4)_我行我素,向往自由的博客-CSDN博客
目录
35.布局管理器
35.1 诞生背景
from PyQt5.Qt import *
import sys
class Window(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('布局管理')
self.resize(500,500)
self.setup_ui()
def setup_ui(self):
label1=QLabel('标签1',self)
label1.setStyleSheet('background-color:cyan;')
label2 = QLabel('标签2', self)
label2.setStyleSheet('background-color:yellow;')
label3 = QLabel('标签3', self)
label3.setStyleSheet('background-color:red;')
timer=QTimer(self)#通过布局管理器方式,会自动压缩
timer.timeout.connect(lambda:label1.setText(label1.text()+'我想你\n'))
timer.start(1000)#1s
#布局管理器实现 ==> 垂直排列,子控件的高度=父控件的高度/3;子控件的宽度=父控件的宽度
v_layout=QVBoxLayout()
v_layout.addWidget(label1)
v_layout.addWidget(label2)
v_layout.addWidget(label3)
self.setLayout(v_layout)
label2.hide()#label2隐藏时候,label3会自动上升填补
if __name__=='__main__':
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
运行效果:
35.2 简单使用
from PyQt5.Qt import *
import sys
class Window(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('布局管理')
self.resize(500,500)
self.setup_ui()
def setup_ui(self):
label1=QLabel('标签1')#不用写self
label1.setStyleSheet('background-color:cyan;')
label2 = QLabel('标签2')
label2.setStyleSheet('background-color:yellow;')
label3 = QLabel('标签3')
label3.setStyleSheet('background-color:red;')
timer=QTimer(self)#通过布局管理器方式,会自动压缩
timer.timeout.connect(lambda:label1.setText(label1.text()+'我想你\n'))
timer.start(500)#0.5s
#布局管理器实现 ==> 垂直排列,子控件的高度=父控件的高度/3;子控件的宽度=父控件的宽度
v_layout=QHBoxLayout()#QHBoxLayout水平布局;QVBoxLayout竖直布局
v_layout.addWidget(label1)
v_layout.addWidget(label2)
v_layout.addWidget(label3)
v_layout.setContentsMargins(20,30,40,50)#左上右下 边距
v_layout.setSpacing(60)#控件之间的距离
self.setLayout(v_layout)
self.setLayoutDirection(Qt.RightToLeft)#设置排列顺序
if __name__=='__main__':
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
运行效果:
35.3 QLayout和QBoxLayout
from PyQt5.Qt import *
import sys
class Window(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('布局管理器的详细使用')
self.resize(500,500)
self.setup_ui()
def setup_ui(self):
label1 = QLabel('标签1') # 不用写self
label1.setStyleSheet('background-color:cyan;')
label2 = QLabel('标签2')
label2.setStyleSheet('background-color:yellow;')
label3 = QLabel('标签3')
label3.setStyleSheet('background-color:red;')
label4=QLabel('标签4')
label4.setStyleSheet('background-color:orange;')
#1.创建一个布局管理器对象
layout=QBoxLayout(QBoxLayout.TopToBottom)#QBoxLayout必须传一个方向参数
#2.直接把布局管理器对象设置给需要布局的父控件
self.setLayout(layout)
# 布局的嵌套
label5 = QLabel('标签5') # 不用写self
label5.setStyleSheet('background-color:pink;')
label6 = QLabel('标签6')
label6.setStyleSheet('background-color:blue;')
label7 = QLabel('标签7')
label7.setStyleSheet('background-color:cyan;')
h_layout = QBoxLayout(QBoxLayout.LeftToRight)
h_layout.addWidget(label5)
h_layout.addWidget(label6)
h_layout.addWidget(label7)
# 3.把需要布局的子控件添加到布局管理器当中
layout.addWidget(label1)
layout.addWidget(h_layout)
layout.addWidget(label2)
layout.addWidget(label3)
layout.setSpacing(60)#label之间的间距
layout.setContentsMargins(10,20,30,40)#外边距,左上右下
print(layout.contentsMargins().left())#查看 10
# layout.replaceWidget(label2,label4)#将label2替换为label4,但必须将label2隐藏
# label2.destroyed.connect(lambda:print('label2被释放'))#没被执行,说明并没有从内存中释放掉
# label2.hide()
if __name__=='__main__':
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
35.3.1 QBoxLayout修改方向
from PyQt5.Qt import *
import sys
class Window(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('QBoxLayout功能作用')
self.resize(500,500)
self.setup_ui()
def setup_ui(self):
label1 = QLabel('标签1') # 不用写self
label1.setStyleSheet('background-color:cyan;')
label2 = QLabel('标签2')
label2.setStyleSheet('background-color:yellow;')
label3 = QLabel('标签3')
label3.setStyleSheet('background-color:red;')
label4 = QLabel('标签4')
label4.setStyleSheet('background-color:orange;')
#1.创建布局管理器对象
layout=QBoxLayout(QBoxLayout.LeftToRight)
#2.把布局管理器对象设置为需要布局的父控件
self.setLayout(layout)
#3.添加需要布局的子控件到布局管理器中
layout.addWidget(label1)
layout.addWidget(label2)
layout.addWidget(label3)
layout.addWidget(label4)
#设置一个定时器,布局每隔1s换一下方向
timer=QTimer(self)
def test():
layout.setDirection((layout.direction()+1)%4)
timer.timeout.connect(test)
timer.start(1000)
if __name__=='__main__':
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
35.3.2 QBoxLayout添加元素
from PyQt5.Qt import *
import sys
class Window(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('QBoxLayout功能作用')
self.resize(500,500)
self.setup_ui()
def setup_ui(self):
label1 = QLabel('标签1') # 不用写self
label1.setStyleSheet('background-color:cyan;')
label2 = QLabel('标签2')
label2.setStyleSheet('background-color:yellow;')
label3 = QLabel('标签3')
label3.setStyleSheet('background-color:red;')
label4 = QLabel('标签4')
label4.setStyleSheet('background-color:orange;')
#1.创建布局管理器对象
layout=QBoxLayout(QBoxLayout.LeftToRight)
#2.把布局管理器对象设置为需要布局的父控件
self.setLayout(layout)
#3.添加需要布局的子控件到布局管理器中
layout.addWidget(label1)
# 添加空白
layout.addSpacing(100)#这个是静态的
layout.addWidget(label2)
layout.addWidget(label3)
# layout.addWidget(label4)
#插入控件
layout.insertWidget(1,label4)#在下标1的位置插入label4
#添加子布局
label5 = QLabel('标签5') # 不用写self
label5.setStyleSheet('background-color:pink;')
label6 = QLabel('标签6')
label6.setStyleSheet('background-color:blue;')
label7 = QLabel('标签7')
label7.setStyleSheet('background-color:cyan;')
h_layout = QBoxLayout(QBoxLayout.TopToBottom)
h_layout.addWidget(label5)
h_layout.addWidget(label6)
h_layout.addWidget(label7)
layout.insertLayout(2,h_layout)#在下标2的地方插入子布局
# #移除控件
# layout.removeWidget(label1)#只是从布局管理器中移除,不再参与布局而已,所以需要隐藏
# label1.hide()#或者label1.setParent(None)#断掉父子关系,就不会显示了
#隐藏子控件:和从布局中删除子控件一样的效果
label1.hide()
label1.show()#会再次参与布局当中,恢复原状
#添加空白(动态的)
layout.insertSpacing(2,60)#下标索引不包括空白区域
if __name__=='__main__':
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
运行效果:
35.3.3 QBoxLayout伸缩因子
from PyQt5.Qt import *
import sys
class Window(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('QBoxLayout功能作用')
self.resize(500,500)
self.setup_ui()
def setup_ui(self):
label1 = QLabel('标签1') # 不用写self
label1.setStyleSheet('background-color:cyan;')
label2 = QLabel('标签2')
label2.setStyleSheet('background-color:yellow;')
label3 = QLabel('标签3')
label3.setStyleSheet('background-color:red;')
label4 = QLabel('标签4')
label4.setStyleSheet('background-color:orange;')
#1.创建布局管理器对象
layout=QBoxLayout(QBoxLayout.LeftToRight)
#2.把布局管理器对象设置为需要布局的父控件
self.setLayout(layout)
#3.添加需要布局的子控件到布局管理器中
layout.addWidget(label1,1)#这个整数就是伸缩因子
layout.addStretch(2)#空白的伸缩
layout.addWidget(label2,2)
layout.addStretch(4)#不断缩小后,空白的伸缩因子会被挤没
layout.addWidget(label3,3)
#插入控件
layout.insertWidget(1,label4,4)#在下标1的位置插入label4,最后一个整数就是伸缩因子
if __name__=='__main__':
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
效果展示:
#修改伸缩因子
layout.setStretchFactor(label2,1)
35.4 QHBoxLayout和QVBoxLayout
35.5 表单布局QFormLayout
35.5.1 行操作
添加行:
from PyQt5.Qt import *
import sys
class Window(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('QFormLayout')
self.resize(500,500)
self.setup_ui()
def setup_ui(self):
name_label=QLabel('姓名(&n):')#alt+n,快速关联
age_label=QLabel('年龄(&g):')#alt+g
name_le=QLineEdit()
age_sb=QSpinBox()
#设置小伙伴
name_label.setBuddy(name_le)
age_label.setBuddy(age_sb)
sex_label=QLabel('性别:')
male_rb=QRadioButton('男')
female_rb=b=QRadioButton('女')
h_layout=QHBoxLayout()#将'男'和'女'这两个控件包起来
h_layout.addWidget(male_rb)
h_layout.addWidget(female_rb)
submit_btn=QPushButton('提交')
#1.创建布局管理器
layout=QFormLayout()
#2.把布局管理器赋值给需要布局的父控件
self.setLayout(layout)
#3.把需要布局的子控件交给布局管理器布局
# layout.addWidget(name_label)
# layout.addWidget(name_le)
#添加行
layout.addRow(name_label,name_le)#只要是两个参数的,就是一行两个控件,一左一右
#或者layout.addRow('姓名(&n):',name_le)#第一个参数是str,但第二个不可以是str
layout.addRow(sex_label,h_layout)
layout.addRow(age_label,age_sb)
# 或者layout.addRow('年龄(&g):',age_sb)
layout.addRow(submit_btn)#也可以只添加一个
if __name__=='__main__':
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
运行效果:
插入行:
与添加行几乎一样,只是增多了一个int型的参数,表示行下标.
获取行信息:
#获取行信息
print('总行数:',layout.rowCount())
print('获取age_sb控件的位置信息:',layout.getWidgetPosition(age_sb))#(2,1)
print('获取子布局的位置信息:',layout.getLayoutPosition(h_layout))#(1,1)
运行效果:
修改行:
#修改行 左侧:LabelRole 右侧:FieldRole
layout.setWidget(0,QFormLayout.LabelRole,name_label)#数字参数代表行号
layout.setWidget(0,QFormLayout.FieldRole,name_le)
layout.setLayout(1,QFormLayout.FieldRole,h_layout)
移除行:
#移除行
# layout.removeRow(2)#移除第二行,行下标从0开始;会释放标签,不需要hide()
# layout.removeRow(age_sb)#会移除age_sb所在的一整行
layout.takeRow(2)#不释放标签,需要hide()
age_sb.hide()
age_label.hide()
#移除一个行中的一个控件,而非一整行
layout.removeWidget(age_label)
age_label.setParent(None)
标签操作:
行的包装策略:
#行的包装策略
layout.setRowWrapPolicy(QFormLayout.WrapAllRows)#WrapAllRows:字段总是位于其标签的下方
效果展示:
35.5.2 对齐与间距
#对齐方式
print(layout.formAlignment()==Qt.AlignLeft | Qt.AlignTop)#True 左对齐,顶部对齐
# layout.setFormAlignment(Qt.AlignLeft | Qt.AlignBottom)#左对齐,下对齐
layout.setFormAlignment(Qt.AlignLeft | Qt.AlignVCenter)#垂直居中
#标签对齐方式
layout.setLabelAlignment(Qt.AlignRight)#标签右对齐
#间距
layout.setHorizontalSpacing(60)#列间距
layout.setVerticalSpacing(60)#行间距
35.5.3 字段增长策略和布局项
35.6 QGridLayout
类似于Excel表格。
35.6.1 元素操作
from PyQt5.Qt import *
import sys
class Window(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('QGridLayout')
self.resize(500,500)
self.setup_ui()
def setup_ui(self):
gl=QGridLayout()
self.setLayout(gl)
label1 = QLabel('标签1') # 不用写self
label1.setStyleSheet('background-color:cyan;')
label2 = QLabel('标签2')
label2.setStyleSheet('background-color:yellow;')
label3 = QLabel('标签3')
label3.setStyleSheet('background-color:red;')
label5 = QLabel('标签5') # 不用写self
label5.setStyleSheet('background-color:pink;')
label6 = QLabel('标签6')
label6.setStyleSheet('background-color:blue;')
label7 = QLabel('标签7')
label7.setStyleSheet('background-color:cyan;')
v_layout=QVBoxLayout()
v_layout.addWidget(label5)
v_layout.addWidget(label6)
v_layout.addWidget(label7)
gl.addWidget(label1,0,0)#占据(0,0)
gl.addWidget(label2,0,1)#占据(0,1)
gl.addWidget(label3,1,0,2,3)#占据(1,0)开始,2行3列
gl.addLayout(v_layout,3,0,1,3)
print(gl.getItemPosition(1))#
if __name__=='__main__':
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
运行效果:
35.6.2 最小列宽行高和拉伸系数
#设置最小行高列宽
gl.setColumnMinimumWidth(0,100)#最小列宽,第0列,列宽100
gl.setRowMinimumHeight(0,100)#最小行高,第0行,行高100
#拉伸系数
gl.setColumnStretch(0,1)
gl.setRowStretch(4,1)
35.6.3 间距控制
35.6.4 信息获取
35.7 QStackedLayout
from PyQt5.Qt import *
import sys
class Window(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('QStackedLayout')
self.resize(500,500)
self.setup_ui()
def setup_ui(self):
#1.创建一个布局管理器对象
sl=QStackedLayout()
#2.把布局对象设置给需要布局的父控件,父布局
self.setLayout(sl)
#3.通过布局对象,管理布局一些子控件
label1 = QLabel('标签1') # 不用写self
label1.setStyleSheet('background-color:cyan;')
label2 = QLabel('标签2')
label2.setStyleSheet('background-color:yellow;')
label3 = QLabel('标签3')
label3.setStyleSheet('background-color:red;')
label4 = QLabel('标签4')
label4.setStyleSheet('background-color:black;')
label5 = QLabel('标签5') # 不用写self
label5.setStyleSheet('background-color:pink;')
label6 = QLabel('标签6')
label6.setStyleSheet('background-color:blue;')
label7 = QLabel('标签7')
label7.setStyleSheet('background-color:cyan;')
v_layout = QVBoxLayout()
v_layout.addWidget(label5)
v_layout.addWidget(label6)
v_layout.addWidget(label7)
print(sl.addWidget(label1))#0
print(sl.addWidget(label2))#1
print(sl.addWidget(label3))#2
#插入控件
print('当前显示的索引位置:',sl.currentIndex())
print(sl.insertWidget(0, label4))#1 ==>如果插入的索引越界,会插入到最后一个
print('当前显示的索引位置:', sl.currentIndex())
#获取控件
print(sl.widget(3).text())
if __name__=='__main__':
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
#切换
sl.setCurrentIndex(2)#设置当前索引为2
#借助定时器,轮流显示所有
timer=QTimer(self)
timer.timeout.connect(lambda:sl.setCurrentIndex((sl.currentIndex()+1)%sl.count()))
timer.start(1000)
#信号
sl.currentChanged.connect(lambda val:print(val))
#展示模式
sl.setStackingMode(QStackedLayout.StackAll)#所有都展示
label1.setFixedSize(100,100)
label2.setFixedSize(150,150)
效果展示:
from PyQt5.Qt import *
import sys
class label(QLabel):
def sizeHint(self):#建议的尺寸大小函数
return QSize(150,60)
class Window(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('尺寸策略')
self.resize(500,500)
self.setup_ui()
def setup_ui(self):
label1 = label('标签1') # 不用写self
label1.setStyleSheet('background-color:cyan;')
label2 = QLabel('标签2')
label2.setStyleSheet('background-color:yellow;')
label3 = QLabel('标签3')
label3.setStyleSheet('background-color:red;')
layout=QVBoxLayout()
self.setLayout(layout)
layout.addWidget(label1)
layout.addWidget(label2)
layout.addWidget(label3)
'''
两个参数,分别指定两个方向。建议尺寸大小,是sizeHint()函数
Fixed:使用建议的尺寸大小,不能压缩也不能伸缩;
Minimum:垂直方向上可压缩可拉伸,但必须参照建议的尺寸大小,不能小于最低
'''
label1.setSizePolicy(QSizePolicy.Fixed,QSizePolicy.Minimum)
if __name__=='__main__':
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())