PyQt5Day30--布局管理

一、布局概念与方式

1、布局概念:布局就是指按照某种规则将子控件摆在父控件中。

2、布局方式:

 1 from PyQt5.Qt import *
 2 
 3 class Window(QWidget):
 4     def __init__(self):
 5         super().__init__()
 6         self.setWindowTitle("布局管理")
 7         self.resize(500, 500)
 8         self.setup_ui()
 9 
10     def setup_ui(self):
11         label1 = QLabel("标签1",self)
12         label1.setStyleSheet("background-color:cyan")
13         label2 = QLabel("标签2", self)
14         label2.setStyleSheet("background-color:yellow")
15         label3 = QLabel("标签3", self)
16         label3.setStyleSheet("background-color:red")
17 
18         # 普通方法
19         # label_widdth = self.width()
20         # label_height = self.height()/3
21         # label1.resize(label_widdth,label_height)
22         # label2.resize(label_widdth,label_height)
23         # label3.resize(label_widdth,label_height)
24 
25         # label1.move(0,0)
26         # label2.move(0,1*label_height)
27         # label3.move(0,2*label_height)
28 
29 
30         # 布局管理方式实现
31         v_layout = QVBoxLayout()
32         v_layout.addWidget(label1)
33         v_layout.addWidget(label2)
34         v_layout.addWidget(label3)
35 
36         self.setLayout(v_layout)
37         label2.hide() # 缺少标签2,内容也会自动调整
38 
39 
40 if __name__ == '__main__':
41     import sys
42 
43     app=QApplication(sys.argv)
44 
45     window=Window()
46     window.show()
47     sys.exit(app.exec_())
简单介绍布局管理的优势

3、布局管理器概念

4、布局的简单使用演示

 1 # 使用演示
 2 label1 = QLabel("标签1")
 3 label1.setStyleSheet("background-color:cyan")
 4 label2 = QLabel("标签2")
 5 label2.setStyleSheet("background-color:yellow")
 6 label3 = QLabel("标签3")
 7 label3.setStyleSheet("background-color:red")
 8 
 9 v_layout = QHBoxLayout()  # 水平方向
10 v_layout.addWidget(label1)
11 v_layout.addWidget(label2)
12 v_layout.addWidget(label3)
13 
14 v_layout.setContentsMargins(20, 30, 40, 50)  # 设置内容的外边距
15 v_layout.setSpacing(30)  # 内容与内容之间
16 
17 self.setLayoutDirection(Qt.RightToLeft)  # 从右到左排序(上面标签)
18 
19 self.setLayout(v_layout)
20 
21 print(self.children())

二、布局管理器的详细使用

1、基类

(1)基类-QLayout

(2)基类-QBoxLayout的功能作用

由于基类的QBoxLayout就是QLayout的子类,因此就一起分析实现。

 1 # *******************基类**********************开始
 2 from PyQt5.Qt import *
 3 
 4 class Window(QWidget):
 5     def __init__(self):
 6         super().__init__()
 7         self.setWindowTitle("基类-QLayout")
 8         self.resize(500, 500)
 9         self.setup_ui()
10 
11     def setup_ui(self):
12         label1 = QLabel("标签1")
13         label1.setStyleSheet("background-color:cyan")
14         label2 = QLabel("标签2")
15         label2.setStyleSheet("background-color:yellow")
16         label3 = QLabel("标签3")
17         label3.setStyleSheet("background-color:red")
18 
19         # 1、传建一个布局管理器对象
20         # layout = QBoxLayout(QBoxLayout.RightToLeft) # 从右到左
21         layout = QBoxLayout(QBoxLayout.BottomToTop) # 从从下到上
22         '''(self, QBoxLayout_Direction, parent=None)'''
23         # 2、直接把布局管理对象设置给需要布局的父控件
24         self.setLayout(layout)
25         # 3、把需要布局的子控件添加到布局管理器中
26         # layout.addWidget(label1)
27         # layout.addWidget(label2)
28         # layout.addWidget(label3)
29 
30         # 设置控件之间的间距
31         layout.setSpacing(20)
32 
33         # 设置外边距
34         print(layout.contentsMargins().left()) # 查看左边间距
35         print(layout.contentsMargins().right()) # 查看右边间距
36         # layout.setContentsMargins(20,20,20,20) # (左上右下)修改
37 
38         # 替换子控件
39         # label4 = QLabel("标签4")
40         # label4.setStyleSheet("background-color:orange")
41         # layout.replaceWidget(label2,label4) # 被替换的控件需要隐藏掉
42         # # label2.hide() # 隐藏,并没有释放掉
43         # label2.setParent(None) # 控件没有父对象就会被释放掉(删除一个控件的办法)
44 
45         # 添加子布局(布局的嵌套)
46         label5 = QLabel("标签5")
47         label5.setStyleSheet("background-color:pink")
48         label6 = QLabel("标签6")
49         label6.setStyleSheet("background-color:blue")
50         label7 = QLabel("标签7")
51         label7.setStyleSheet("background-color:green")
52 
53         h_layout = QBoxLayout(QBoxLayout.LeftToRight)
54         h_layout.addWidget(label5)
55         h_layout.addWidget(label6)
56         h_layout.addWidget(label7)
57 
58         # 3、把需要布局的子控件添加到布局管理器中
59         layout.addWidget(label1)
60         layout.addLayout(h_layout)
61         layout.addWidget(label2)
62         layout.addWidget(label3)
63 
64         # 能用性
65         layout.setEnabled(False) # 布局管理器失效
66 
67 
68 if __name__ == '__main__':
69     import sys
70 
71     app=QApplication(sys.argv)
72 
73     window=Window()
74     window.show()
75     sys.exit(app.exec_())
76 # *******************基类**********************结束
基类Layout中的功能作用
 1 # *******************基类-QBoxLayout**********************开始
 2 from PyQt5.Qt import *
 3 
 4 class Window(QWidget):
 5     def __init__(self):
 6         super().__init__()
 7         self.setWindowTitle("类-QBoxLayout")
 8         self.resize(500, 500)
 9         self.setup_ui()
10 
11     def setup_ui(self):
12         label1 = QLabel("标签1")
13         label1.setStyleSheet("background-color:cyan")
14         label2 = QLabel("标签2")
15         label2.setStyleSheet("background-color:yellow")
16         label3 = QLabel("标签3")
17         label3.setStyleSheet("background-color:red")
18         label4 = QLabel("标签4")
19         label4.setStyleSheet("background-color:orange")
20 
21         # 1、创建布局管理器对象
22         layout = QBoxLayout(QBoxLayout.LeftToRight)
23         # 2、把布局管理器对象设置给需要布局的父控件
24         self.setLayout(layout)
25         # # 3、添加需要布局的子控件到布局管理器中
26         # layout.addWidget(label1)
27         #
28         # 添加空白(空白盒子,方便布局)
29         # layout.addSpacing(40)
30 
31         # layout.addWidget(label2)
32         # layout.addWidget(label3)
33         # layout.addWidget(label4)
34 
35         # 修改方向
36         # timer = QTimer(self)
37         # def test():
38         #     layout.setDirection((layout.direction()+1)%4) # 0--3之间循环,不同值代表不同方向(类属性值)
39         # timer.timeout.connect(test)
40         # timer.start(1000)
41 
42         # 添加元素(也可以插入布局insertLayout)
43         # layout.insertWidget(1,label4) # 1代表位置
44 
45         # 移除控件
46         # layout.removeWidget(label1) # 也只是从布局管理器中移除,本身还是在
47 
48         # 插入空白
49         # layout.insertSpacing(4,30)
50 
51         # 添加伸缩(弹簧)
52         layout.addWidget(label1,1)
53         layout.addStretch(2) # 空白伸缩因子,可以压缩到没有
54         layout.addWidget(label2,1)
55         layout.addStretch(2)
56         layout.addWidget(label3,1)
57         # layout.addWidget(label4)
58 
59         layout.setStretchFactor(label2,2) # 给标签2设置伸缩因子(也可以给子布局设置)
60 
61 if __name__ == '__main__':
62     import sys
63 
64     app=QApplication(sys.argv)
65 
66     window=Window()
67     window.show()
68     sys.exit(app.exec_())
69 # *******************基类-QBoxLayout**********************结束
基类QBoxLayout中的功能作用

2、QHBoxLayout与QVBoxLayout

3、QFormLayout表单布局

 

(1)构造函数

(2)行操作

 1 from PyQt5.Qt import *
 2 
 3 class Window(QWidget):
 4     def __init__(self):
 5         super().__init__()
 6         self.setWindowTitle("QFormLayout")
 7         self.resize(500, 500)
 8         self.setup_ui()
 9 
10     def setup_ui(self):
11         # name_label = QLabel("姓名(&n):")
12         # age_label = QLabel("年龄(&g):")
13         sex_label = QLabel("性别")
14 
15         name_le = QLineEdit()
16         age_sb = QSpinBox()
17 
18         submit_btn = QPushButton("提交")
19         male_rb = QRadioButton("")
20         female_rb = QRadioButton("")
21 
22         # 添加小伙伴
23         # name_label.setBuddy(name_le)
24         # age_label.setBuddy(age_sb)
25 
26         # 性别布局
27         h_layout = QHBoxLayout()
28         h_layout.addWidget(male_rb)
29         h_layout.addWidget(female_rb)
30 
31         # 1、创建布局管理器
32         layout = QFormLayout()
33         # 2、把布局管理器赋值给需要布局的父控件
34         self.setLayout(layout)
35         # 3、把需要布局的子控件交给布局管理器进行布局
36         # layout.addWidget(name_lable)
37         # layout.addWidget(name_le)
38         # layout.addRow(name_label,name_le) # 行操作
39         layout.addRow("姓名(&n)",name_le) # 行操作实现创建姓名标签与小伙伴
40         layout.addRow(sex_label,h_layout) # 行操作-添加子布局
41         # layout.addRow(age_label,age_sb)
42         layout.addRow("年龄(&g)",age_sb) # 行操作实现创建年龄标签与小伙伴
43         layout.addRow(submit_btn)
44 
45 if __name__ == '__main__':
46     import sys
47 
48     app=QApplication(sys.argv)
49 
50     window=Window()
51     window.show()
52     sys.exit(app.exec_())
添加行操作
 1 from PyQt5.Qt import *
 2 
 3 class Window(QWidget):
 4     def __init__(self):
 5         super().__init__()
 6         self.setWindowTitle("QFormLayout")
 7         self.resize(500, 500)
 8         self.setup_ui()
 9 
10     def setup_ui(self):
11         name_le = QLineEdit()
12         age_sb = QSpinBox()
13 
14         submit_btn = QPushButton("提交")
15         male_rb = QRadioButton("")
16         female_rb = QRadioButton("")
17 
18         # 性别布局
19         h_layout = QHBoxLayout()
20         h_layout.addWidget(male_rb)
21         h_layout.addWidget(female_rb)
22 
23         # 1、创建布局管理器
24         layout = QFormLayout()
25         # 2、把布局管理器赋值给需要布局的父控件
26         self.setLayout(layout)
27         # 3、把需要布局的子控件交给布局管理器进行布局
28         # layout.addRow("姓名(&n)",name_le) # 行操作实现创建姓名标签与小伙伴
29         # layout.addRow("年龄(&g)",age_sb) # 行操作实现创建年龄标签与小伙伴
30         # layout.addRow(submit_btn)
31         # 插入行
32         # layout.insertRow(1,"性别:",h_layout)
33 
34         # 获取行
35         # print(layout.rowCount())
36         # print(layout.getWidgetPosition(age_sb))
37         # print(layout.getLayoutPosition(h_layout))
38 
39         # 修改行
40         name_label = QLabel("姓名:")
41         layout.setWidget(0,QFormLayout.LabelRole,name_label) # 作边添加标签角色
42         layout.setWidget(0,QFormLayout.FieldRole,name_le) # 右边添加文本角色
43 
44 
45 if __name__ == '__main__':
46     import sys
47 
48     app=QApplication(sys.argv)
49 
50     window=Window()
51     window.show()
52     sys.exit(app.exec_())
插入行、获取行和修改行
 1 from PyQt5.Qt import *
 2 
 3 class Window(QWidget):
 4     def __init__(self):
 5         super().__init__()
 6         self.setWindowTitle("QFormLayout")
 7         self.resize(500, 500)
 8         self.setup_ui()
 9 
10     def setup_ui(self):
11         sex_label = QLabel("性别:")
12         name_le = QLineEdit()
13         age_sb = QSpinBox()
14 
15         submit_btn = QPushButton("提交")
16         male_rb = QRadioButton("")
17         female_rb = QRadioButton("")
18 
19         # 性别布局
20         h_layout = QHBoxLayout()
21         h_layout.addWidget(male_rb)
22         h_layout.addWidget(female_rb)
23 
24         # 1、创建布局管理器
25         layout = QFormLayout()
26         # 2、把布局管理器赋值给需要布局的父控件
27         self.setLayout(layout)
28         # 3、把需要布局的子控件交给布局管理器进行布局
29         layout.addRow("姓名(&n)",name_le) # 行操作实现创建姓名标签与小伙伴
30         layout.addRow("年龄(&g)",age_sb) # 行操作实现创建年龄标签与小伙伴
31         layout.addRow(sex_label,h_layout)
32         layout.addRow(submit_btn)
33 
34         # 移除行
35         # layout.removeRow(1) # 移除第二行控件(但是没有释放)
36         # layout.removeWidget(sex_label) # 移除某一控件
37         # layout.takeRow(1) # 拿走第二个控件,影响布局
38 
39         # 标签操作:修改名字样式(姓名——name)
40         print(layout.labelForField(name_le)) # 拿到QLabel对象
41         layout.labelForField(name_le).setText('name') # 修改标签
42         
43 
44 if __name__ == '__main__':
45     import sys
46 
47     app=QApplication(sys.argv)
48 
49     window=Window()
50     window.show()
51     sys.exit(app.exec_())
移除行、标签操作

(3)行的包装策略

 

1 # 行的包装策略
2 # layout.setRowWrapPolicy(QFormLayout.WrapAllRows) # 文本始终位于标签下面
3 layout.setRowWrapPolicy(QFormLayout.WrapLongRows) # 标签不变,文本若是放不下,自动跳转到下一行

(4)对齐方式

1 # 对齐方式
2 print(layout.formAlignment() == Qt.AlignLeft | Qt.AlignTop) # True
3 # layout.setFormAlignment(Qt.AlignLeft | Qt.AlignBottom) # 左对齐+底部对齐
4 layout.setLabelAlignment(Qt.AlignCenter) # 居中对齐间距

(5)间距

1 # 间距
2 layout.setVerticalSpacing(40)  # 垂直方向间距
3 layout.setHorizontalSpacing(40)  # 水平方向间距

(6)字段增长策略

1 # 字段增长策略
2 layout.setFieldGrowthPolicy(QFormLayout.FieldsStayAtSizeHint) # 保持原样不跟着改变

4、QGridLayout网格布局

(1)构造函数

(2)元素操作

 1 from PyQt5.Qt import *
 2 
 3 class Window(QWidget):
 4     def __init__(self):
 5         super().__init__()
 6         self.setWindowTitle("QGridLayout")
 7         self.resize(500, 500)
 8         self.setup_ui()
 9 
10     def setup_ui(self):
11         gl = QGridLayout()
12         self.setLayout(gl)
13         label1 = QLabel("标签1")
14         label1.setStyleSheet("background-color:cyan")
15         label2 = QLabel("标签2")
16         label2.setStyleSheet("background-color:yellow")
17         label3 = QLabel("标签3")
18         label3.setStyleSheet("background-color:green")
19 
20         label4 = QLabel("标签4")
21         label4.setStyleSheet("background-color:blue")
22         label5 = QLabel("标签5")
23         label5.setStyleSheet("background-color:red")
24         label6 = QLabel("标签6")
25         label6.setStyleSheet("background-color:pink")
26 
27         # 元素操作
28         gl.addWidget(label1,0,0)
29         gl.addWidget(label2,0,1)
30         # gl.addWidget(label3,1,0,1,2) # 从第1行的第0列开始,合并1行2列
31         gl.addWidget(label3,1,0,2,2) # 从第1行的第0列开始,合并1行2列
32 
33         layout = QVBoxLayout()
34         layout.addWidget(label4)
35         layout.addWidget(label5)
36         layout.addWidget(label6)
37         gl.addLayout(layout,3,0,1,3) # 添加子布局
38 
39         print(gl.getItemPosition(0)) # 标签1的位置及所占大小
40         print(gl.getItemPosition(2)) # 标签3的位置及所占大小
41         print(gl.itemAtPosition(0,1).widget().text()) # 查看某个位置是什么标签
42 
43 if __name__ == '__main__':
44     import sys
45 
46     app=QApplication(sys.argv)
47 
48     window=Window()
49     window.show()
50     sys.exit(app.exec_())
元素操作

(3)列宽/行高和拉伸系数

1 # 列宽/行高和拉伸系数
2 # gl.setColumnMinimumWidth(0,100) # 设置标签1的最小宽度100
3 # gl.setRowMinimumHeight(0,100) # 设置第0行的最小高度为100
4 
5 gl.setColumnStretch(0, 2)  # 第0列拉伸系数为2
6 gl.setColumnStretch(1, 1)  # 第2列拉伸系数为1
7 
8 gl.setRowStretch(3, 1) 
列宽/行高和拉伸系数

(4)间距

1 # 间距
2 print(gl.spacing())
3 # gl.setVerticalSpacing(20) # 行与行之间间距设置
4 # gl.setHorizontalSpacing(20) # 行与行之间间距设置
5 gl.setSpacing(60)  # 统一设置

(5)原点角

1 # 原点角
2 gl.setOriginCorner(Qt.TopRightCorner)  # 原点角位于右上角
3 gl.setOriginCorner(Qt.BottomLeftCorner)  # 原点角位于左上角

(6)信息获取

1 # 信息获取
2 print(gl.rowCount())
3 print(gl.columnCount())
4 
5 # 注意cellRect的获取
6 gl = window.layout()
7 print(gl.cellRect(0, 0))

5、QStackedLayout堆叠布局

# *******************QStackedLayout**********************开始
from PyQt5.Qt import *

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")
        label1.setStyleSheet("background-color:cyan")
        label2 = QLabel("标签2")
        label2.setStyleSheet("background-color:yellow")
        label3 = QLabel("标签3")
        label3.setStyleSheet("background-color:green")

        label4 = QLabel("标签4")
        label4.setStyleSheet("background-color:blue")
        label5 = QLabel("标签5")
        label5.setStyleSheet("background-color:red")
        label6 = QLabel("标签6")
        label6.setStyleSheet("background-color:pink")

        v_layout = QVBoxLayout()
        v_layout.addWidget(label4)
        v_layout.addWidget(label5)
        v_layout.addWidget(label6)

        sl.addWidget(label1)
        sl.addWidget(label2)
        sl.addWidget(label3)

        sl.insertWidget(1,label4)

        # 通过索引值来指定展示的标签
        # sl.setCurrentIndex(2)
        # timer = QTimer(self)
        # timer.timeout.connect(lambda :sl.setCurrentIndex((sl.currentIndex()+1)%sl.count()))
        # timer.start(1000)

        # 信号-currentChanged
        # sl.currentChanged.connect(lambda val:print(val))

        # 展示模式
        sl.setStackingMode(QStackedLayout.StackAll) # 所有小部件可见(默认是不可见),只展示一个
        label1.hide()

        # 信号-
        sl.widgetRemoved.connect(lambda :print("控件被移除"))
        sl.removeWidget(label2)

if __name__ == '__main__':
    import sys

    app=QApplication(sys.argv)

    window=Window()
    window.show()
    sys.exit(app.exec_())
# *******************QStackedLayout**********************结束
AStackedLayout堆叠布局

三、布局管理补充--尺寸策略

1、QWidget.sizeHint( )

2、QWidget.minimumSizeHint( )

 

 3、控件的尺寸策略

(1)作用

(2)使用方式

 1 # *******************布局管理的补充-尺寸策略**********************开始
 2 from PyQt5.Qt import *
 3 
 4 class Label(QLabel):
 5     # def minimumSizeHint(self):
 6     #     return QSize(200,200)
 7 
 8     def sizeHint(self):
 9         return QSize(150,60)
10 
11 class Window(QWidget):
12     def __init__(self):
13         super().__init__()
14         self.setWindowTitle("补充-尺寸策略")
15         self.resize(500, 500)
16         self.setup_ui()
17 
18     def setup_ui(self):
19         # label1 = QLabel("标签1")
20         label1 = Label("标签1") # 自定义建议大小,并返回
21         label1.setStyleSheet("background-color:cyan")
22         label2 = QLabel("标签2")
23         label2.setStyleSheet("background-color:yellow")
24         label3 = QLabel("标签3")
25         label3.setStyleSheet("background-color:green")
26 
27         layout = QVBoxLayout()
28         self.setLayout(layout)
29         layout.addWidget(label1)
30         layout.addWidget(label2)
31         layout.addWidget(label3)
32 
33         # 尺寸策略
34         # label1.setSizePolicy(QSizePolicy.Fixed,QSizePolicy.Fixed) # 尺寸策略,固定label1的尺寸
35         # label1.setSizePolicy(QSizePolicy.Fixed,QSizePolicy.Maximum) # 尺寸策略,固定水平,垂直不能超过建议的最大值
36         # label1.setSizePolicy(QSizePolicy.Fixed,QSizePolicy.Preferred) # 标签1优先
37         # label2.setSizePolicy(QSizePolicy.Fixed,QSizePolicy.Expanding)
38         sp = QSizePolicy(QSizePolicy.Fixed,QSizePolicy.Ignored)
39         sp.setRetainSizeWhenHidden(True) # 保留标签1隐藏的控件
40         label1.setSizePolicy(sp)
41 
42         label1.hide()
43 
44         label2.setFixedSize(200,200) # 固定标签2的尺寸,无论什么策略,固定的级别最高
45 
46 if __name__ == '__main__':
47     import sys
48 
49     app=QApplication(sys.argv)
50 
51     window=Window()
52     window.show()
53     sys.exit(app.exec_())
54 # *******************布局管理的补充-尺寸策略**********************结束
尺寸策略

 

posted @ 2020-05-07 17:38  红叶楠木  阅读(319)  评论(0编辑  收藏  举报