zoukankan      html  css  js  c++  java
  • 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 # *******************布局管理的补充-尺寸策略**********************结束
    尺寸策略
  • 相关阅读:
    LeetCode 11. Container With Most Water
    LeetCode 10 Regular Expression Matching
    LeetCode 9 Palindrome Number
    LeetCode 8 String to Integer (atoi)
    从ASP.NET Core 3.0 preview 特性,了解CLR的Garbage Collection
    HttpClient参观记:.net core 2.2 对HttpClient到底做了神马
    LeetCode 7 Reverse Integer
    《地久天长》观影笔记
    《小丑》观后感
    粒子群基本算法学习笔记
  • 原文地址:https://www.cnblogs.com/fengxb1213/p/12835995.html
Copyright © 2011-2022 走看看