PyQt5—布局管理

布局管理

  • PyQt5 布局管理
    • 一、PyQt5 中的布局管理
    • 二、绝对位置布局
      • 1、代码示例
      • 2、绝对布局的优缺点
    • 三、QBoxLayout(框布局)
      • 1、QHBoxLayout
        • 1.1、个性化设置
      • 2、QVBoxLayout
      • 3、addStretch(int stretch=0) 函数
    • 四、网格布局
      • 1、单一的网格单元格
      • 2、跨越行列式单元网格
    • 五、表单布局
    • 六、嵌套布局
      • 1、在布局中添加其他布局
      • 2、在控件中添加布局
    • 七、QSplitter

PyQt5 布局管理

一、PyQt5 中的布局管理

  • PyQt5 的界面进行布局管理主要有两种方法:绝对位置和布局类;布局方式有四种:水平布局、网格布局、垂直布局和表单布局;两种布局方法:addWidget() 和 addLayout() ,前者用于在布局中插入控件,后者在布局中插入子布局。
  • 四种布局方式对应四种布局类:
    • 水平布局类(QHBoxLayout),将控件在水平上依次排列。
    • 垂直布局类(QVBoxLayout),将控件在垂直方向上依次排列。
    • 网格布局类(QGridLayout),将控件以网格的形式排列。
    • 表单布局类(QFormLayout),将控件以两列的形式排列。

二、绝对位置布局

  • 绝对位置布局(Absolute Positioning Layout)主要通过在窗口程序指定每一个控件的显示坐标和大小来实现。以屏幕(容器)左上角为原点,从左向右为横坐标,从上到下为纵坐标。

1、代码示例

  • 绝对布局示例代码如下:
    # -*- coding:utf-8 -*-
    # Time : 2019/08/31 下午 3:50 
    # Author : 御承扬
    # e-mail:[email protected]
    # project:  PyQt5
    # File : AbsolutePositionTest.py 
    # @software: PyCharm
    
    
    import sys
    from PyQt5.QtGui import QIcon
    from PyQt5.QtWidgets import QWidget, QLabel, QApplication
    
    
    class TestExample(QWidget):
        def __init__(self):
            super(TestExample, self).__init__()
            self.initUI()
    
        def initUI(self):
            lbl1 = QLabel('欢迎', self)
            lbl1.move(15, 10)
            lbl2 = QLabel('学习', self)
            lbl2.move(35, 40)
            lbl3 = QLabel('PyQt5 !', self)
            lbl3.move(55, 70)
            self.setGeometry(300, 300, 320, 120)
            self.setWindowIcon(QIcon("./images/Python2.ico"))
            self.setWindowTitle("绝对布局示例")
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        demo = TestExample()
        demo.show()
        sys.exit(app.exec_())
    
  • 效果如下:
    PyQt5—布局管理_第1张图片

2、绝对布局的优缺点

  • 绝对布局的优点是,可以直接定位每个控件的位置。
  • 缺点是窗口中的控件大小和位置不会随着窗口大小的调整而调整,同时所生成的窗口在不同操作系统下看起来不一致,以及修改字体时可能破坏布局,一旦布局确定后想重新添加控件非常麻烦,需要重新布局。

三、QBoxLayout(框布局)

  • QBoxLayout 类支持在水平和垂直方向上排列控件,其子类有 QHBoxLayout(水平布局) 和 QVBoxLayout(垂直布局)。

1、QHBoxLayout

  • QHBoxLayout,水平布局,顾名思义,是一种水平方向上从左向右的顺序添加控件的布局方式。
  • QHBoxLayout 类的常用方法如下:
    方法 描述
    addLayout(self, QLayout, stretch = 0) 在窗口的右边添加布局,使用 strtch(伸缩量)进行伸缩,默认伸缩量为 0.
    addWidget(self, QWidget, stretch, Qt.Alignment alignment) 在布局中添加控件,伸缩量只适用于 QBoxLayout,控件和窗口会随着伸缩量的变大而变大
    addSpacing(self, int) 设置各控件的上下间距,通过该方法可以设置增加额外的空间
  • 水平布局的示例代码如下:
    # -*- coding:utf-8 -*-
    # Time : 2019/08/31 下午 8:17 
    # Author : 御承扬
    # e-mail:[email protected]
    # project:  PyQt5
    # File : HBoxLayoutTest.py 
    # @software: PyCharm
    
    
    import sys
    from PyQt5.QtWidgets import *
    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    
    
    class WinForm(QWidget):
        def __init__(self, parent=None):
            super(WinForm, self).__init__(parent)
            self.setWindowTitle("水平布局示例")
            self.setWindowIcon(QIcon("./images/Python2.ico"))
            hLayout = QHBoxLayout()
            hLayout.addWidget(QPushButton(str(1)))
            hLayout.addWidget(QPushButton(str(2)))
            hLayout.addWidget(QPushButton(str(3)))
            hLayout.addWidget(QPushButton(str(4)))
            hLayout.addWidget(QPushButton(str(5)))
            self.setLayout(hLayout)
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        win = WinForm()
        win.show()
        sys.exit(app.exec_())
    

1.1、个性化设置

  • 可以根据需要,对水平布局进行对齐方式和控件间距等个性化设置。
  • 对齐方式主要通过对齐方式参数 Qt.Alignment 来设置,示例:
    self.resize(550, 400)
    hLayout = QHBoxLayout()
    hLayout.addWidget(QPushButton(str(1)), 0, Qt.AlignTop)
    hLayout.addWidget(QPushButton(str(2)), 0, Qt.AlignLeft | Qt.AlignTop)
    hLayout.addWidget(QPushButton(str(3)))
    hLayout.addWidget(QPushButton(str(4)), 0, Qt.AlignLeft | Qt.AlignBottom)
    hLayout.addWidget(QPushButton(str(5)), 0, Qt.AlignLeft | Qt.AlignBottom)
    
    PyQt5—布局管理_第2张图片
  • 设置控件之间的间距,使用 setSpacing(int) 方法来设置,示例代码如下:
    hLayout = QHBoxLayout()
    hLayout.addWidget(QPushButton(str(1)))
    hLayout.addWidget(QPushButton(str(2)))
    hLayout.addWidget(QPushButton(str(3)))
    hLayout.addWidget(QPushButton(str(4)))
    hLayout.addWidget(QPushButton(str(5)))
    hLayout.setSpacing(0)
    self.setLayout(hLayout)
    

2、QVBoxLayout

  • QVBoxLayout 类,支持从上到下的顺序添加控件,示例代码如下:
    # -*- coding:utf-8 -*-
    # Time : 2019/09/01 下午 2:38 
    # Author : 御承扬
    # e-mail:[email protected]
    # project:  PyQt5
    # File : VBoxLayoutTest.py 
    # @software: PyCharm
    
    
    import sys
    from PyQt5.QtWidgets import *
    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    
    
    class WinForm(QWidget):
        def __init__(self, parent=None):
            super(WinForm, self).__init__(parent)
            self.setWindowTitle('垂直布局示例')
            self.setWindowIcon(QIcon("./images/Python2.ico"))
            vLayout = QVBoxLayout()
            vLayout.addWidget(QPushButton(str(1)))
            vLayout.addWidget(QPushButton(str(2)))
            vLayout.addWidget(QPushButton(str(3)))
            vLayout.addWidget(QPushButton(str(4)))
            vLayout.addWidget(QPushButton(str(5)))
            self.setLayout(vLayout)
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        win = WinForm()
        win.show()
        sys.exit(app.exec_())
    

3、addStretch(int stretch=0) 函数

  • addStretch(int stretch=0) 函数用于在布局管理器中增加一个可伸缩的控件(QSpaceItem),0 为最小值,并且将 stretch 作为伸缩量添加到布局末尾。
  • 示例
    # -*- coding:utf-8 -*-
    # Time : 2019/09/01 下午 2:51 
    # Author : 御承扬
    # e-mail:[email protected]
    # project:  PyQt5
    # File : StretchTest01.py 
    # @software: PyCharm
    
    
    import sys
    from PyQt5.QtWidgets import *
    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    
    
    class WinForm(QWidget):
        def __init__(self):
            super(WinForm, self).__init__()
            btn1 = QPushButton(self)
            btn2 = QPushButton(self)
            btn3 = QPushButton(self)
            btn1.setText('button 1')
            btn2.setText('button 2')
            btn3.setText('button 3')
            hBox = QHBoxLayout()
            # 设置伸缩量为 1
            hBox.addStretch(1)
            hBox.addWidget(btn1)
            hBox.addStretch(1)
            hBox.addWidget(btn2)
            hBox.addStretch(1)
            hBox.addWidget(btn3)
            hBox.addStretch(1)
            self.setLayout(hBox)
            self.setWindowTitle("addStretch Demo")
            self.setWindowIcon(QIcon("./images/Python2.ico"))
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        win = WinForm()
        win.show()
        sys.exit(app.exec_())
    
  • 效果如下:
    PyQt5—布局管理_第3张图片
  • 如果在第一个控件之前添加伸缩控件,那么所有的控件都会居右显示;反之,如果在最后一个控件之后添加伸缩控件,呢么所有的孔家都会居左显示。

四、网格布局

  • 网格布局,将窗口拆分成行和列来放置控件,通常使用 addWidget() 函数添加控件,用 addLayout() 添加子布局。

1、单一的网格单元格

  • 示例代码如下:
    # -*- coding:utf-8 -*-
    # Time : 2019/09/01 下午 3:51 
    # Author : 御承扬
    # e-mail:[email protected]
    # project:  PyQt5
    # File : GridLayoutTesto1.py 
    # @software: PyCharm
    
    
    import sys
    from PyQt5.QtWidgets import *
    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    
    
    class WinForm(QWidget):
        def __init__(self, parent=None):
            super(WinForm, self).__init__()
            self.initUI()
    
        def initUI(self):
            grid = QGridLayout()
            self.setLayout(grid)
            names = ['Cls', 'Back', '', 'Close',
                     '7', '8', '9', '/',
                     '4', '5', '6', '*',
                     '1', '2', '3', '-',
                     '0', '.', '=', '+']
            positions = [(i, j) for i in range(5) for j in range(4)]
            for position, name in zip(positions, names):
                if name == '':
                    continue
                button = QPushButton(name)
                grid.addWidget(button, *position)
    
            self.move(300, 150)
            self.setWindowIcon(QIcon("./images/Python2.ico"))
            self.setWindowTitle('GridLayout Demo')
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        win = WinForm()
        win.show()
        sys.exit(app.exec_())
    
  • 效果如下:
    PyQt5—布局管理_第4张图片

2、跨越行列式单元网格

  • 除了一个网格一个控件,还可以一个控件占据多个行列,示例代码如下:
    # -*- coding:utf-8 -*-
    # Time : 2019/09/02 下午 2:28 
    # Author : 御承扬
    # e-mail:[email protected]
    # project:  PyQt5
    # File : GridLayoutTest02.py 
    # @software: PyCharm
    
    
    import sys
    from PyQt5.QtWidgets import *
    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    
    
    class WinForm(QWidget):
        def __init__(self, parent=None):
            super(WinForm, self).__init__(parent)
            self.initUI()
    
        def initUI(self):
            name = QLabel('昵称')
            hobby = QLabel('兴趣爱好')
            signature = QLabel('个性签名')
    
            nameEdit = QLineEdit()
            hobbyEdit = QLineEdit()
            signatureEdit = QTextEdit()
            grid = QGridLayout()
            grid.setSpacing(10)
            grid.addWidget(name, 1, 0)
            grid.addWidget(nameEdit, 1, 1)
            grid.addWidget(hobby, 2, 0)
            grid.addWidget(hobbyEdit, 2, 1)
            grid.addWidget(signature, 3, 0)
            grid.addWidget(signatureEdit, 3, 1, 5, 1)
            self.setLayout(grid)
            self.setGeometry(300, 300, 350, 300)
            self.setWindowIcon(QIcon("./images/Python2.ico"))
            self.setWindowTitle('个人信息完善')
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        win = WinForm()
        win.show()
        sys.exit(app.exec_())
    
  • 效果如下:
    PyQt5—布局管理_第5张图片

五、表单布局

  • 表单布局,QFormLayout,实现 label-field 式表单布局的布局控件,主要有两列构成:信息提示区域和信息输入区域,前者也叫 label 域,后者也叫 field 域。
  • 示例代码如下:
    # -*- coding:utf-8 -*-
    # Time : 2019/09/03 下午 4:15 
    # Author : 御承扬
    # e-mail:[email protected]
    # project:  PyQt5
    # File : formLayoutTest.py 
    # @software: PyCharm
    
    
    import sys
    from PyQt5.QtWidgets import *
    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    
    
    class WinForm(QWidget):
        def __init__(self, parent=None):
            super(WinForm, self).__init__(parent)
            self.setWindowTitle('FormLayout Demo')
            self.setWindowIcon(QIcon("./images/Python2.ico"))
            self.resize(400, 100)
            formLayout = QFormLayout()
            lbl1 = QLabel("姓名:")
            lineEdit1 = QLineEdit()
            lbl2 = QLabel("民族:")
            lineEdit2 = QLineEdit()
            lbl3 = QLabel("籍贯:")
            lineEdit3 = QLineEdit()
            formLayout.addRow(lbl1, lineEdit1)
            formLayout.addRow(lbl2, lineEdit2)
            formLayout.addRow(lbl3, lineEdit3)
            self.setLayout(formLayout)
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        win = WinForm()
        win.show()
        sys.exit(app.exec_())
    
  • 效果如下:
    PyQt5—布局管理_第6张图片

六、嵌套布局

  • 嵌套布局,是指将 PyQt5 的各种布局综合起来使用,不在单独使用某种布局。主要方法有往布局中添加布局和往控件中添加布局。

1、在布局中添加其他布局

  • 将使用的多种布局中,选择某一个或更多作为全局布局,其余作为该全局布局的子布局,示例代码如下:
    # -*- coding:utf-8 -*-
    # Time : 2019/09/03 下午 7:49 
    # Author : 御承扬
    # e-mail:[email protected]
    # project:  PyQt5
    # File : nestLayout01.py 
    # @software: PyCharm
    
    
    import sys
    from PyQt5.QtWidgets import *
    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    
    
    class WinForm(QWidget):
        def __init__(self):
            super(WinForm, self).__init__()
            self.setWindowTitle("Nested Layout Demo")
            self.setWindowIcon(QIcon("./images/Python2.ico"))
            # 全局布局(2 种):水平
            wLayout = QHBoxLayout()
            # 局部布局( 4 种):水平、垂直、网格、表单
            hLayout = QHBoxLayout()
            vLayout = QVBoxLayout()
            gLayout = QGridLayout()
            fLayout = QFormLayout()
    
            # 往局部布局添加控件
            hLayout.addWidget(QPushButton(str(1)))
            hLayout.addWidget(QPushButton(str(2)))
            vLayout.addWidget(QPushButton(str(3)))
            vLayout.addWidget(QPushButton(str(4)))
            gLayout.addWidget(QPushButton(str(5)), 0, 0)
            gLayout.addWidget(QPushButton(str(6)), 0, 1)
            gLayout.addWidget(QPushButton(str(7)), 1, 0)
            gLayout.addWidget(QPushButton(str(8)), 1, 1)
            fLayout.addWidget(QPushButton(str(9)))
            fLayout.addWidget(QPushButton(str(10)))
            fLayout.addWidget(QPushButton(str(11)))
            fLayout.addWidget(QPushButton(str(12)))
    
            # 创建四个 QWidget 类,用于放置四种子布局
            hwg = QWidget()
            vwg = QWidget()
            gwg = QWidget()
            fwg = QWidget()
    
            # 添加子布局
            hwg.setLayout(hLayout)
            vwg.setLayout(vLayout)
            gwg.setLayout(gLayout)
            fwg.setLayout(fLayout)
            wLayout.addWidget(hwg)
            wLayout.addWidget(vwg)
            wLayout.addWidget(gwg)
            wLayout.addWidget(fwg)
    
            # 添加全局布局
            self.setLayout(wLayout)
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        win = WinForm()
        win.show()
        sys.exit(app.exec_())
    
  • 效果如下:
    PyQt5—布局管理_第7张图片

2、在控件中添加布局

  • 不同于上一种方式中,四种布局需要四种空白控件,这一种方式可以做到无论有多少中布局方式,只需要一个空白控件,示例代码如下:
    # -*- coding:utf-8 -*-
    # Time : 2019/09/03 下午 8:23 
    # Author : 御承扬
    # e-mail:[email protected]
    # project:  PyQt5
    # File : nestLayout02.py 
    # @software: PyCharm
    
    
    import sys
    from PyQt5.QtWidgets import *
    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    
    
    class WinForm(QWidget):
        def __init__(self):
            super(WinForm, self).__init__()
            self.setWindowTitle('Nested Layout Demo')
            self.setWindowIcon(QIcon("./images/Python2.ico"))
            self.resize(700, 200)
            # 全局控件,用于承载全局布局
            wwg = QWidget(self)
            # 全局布局
            wl = QHBoxLayout(wwg)
            hLayout = QHBoxLayout()
            vLayout = QVBoxLayout()
            gLayout = QGridLayout()
            fLayout = QFormLayout()
    
            # 往局部布局添加控件
            hLayout.addWidget(QPushButton(str(1)))
            hLayout.addWidget(QPushButton(str(2)))
            vLayout.addWidget(QPushButton(str(3)))
            vLayout.addWidget(QPushButton(str(4)))
            gLayout.addWidget(QPushButton(str(5)), 0, 0)
            gLayout.addWidget(QPushButton(str(6)), 0, 1)
            gLayout.addWidget(QPushButton(str(7)), 1, 0)
            gLayout.addWidget(QPushButton(str(8)), 1, 1)
            fLayout.addWidget(QPushButton(str(9)))
            fLayout.addWidget(QPushButton(str(10)))
            fLayout.addWidget(QPushButton(str(11)))
            fLayout.addWidget(QPushButton(str(12)))
    
            # 将子布局添加到全局布局中
            wl.addLayout(hLayout)
            wl.addLayout(vLayout)
            wl.addLayout(gLayout)
            wl.addLayout(fLayout)
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        win = WinForm()
        win.show()
        sys.exit(app.exec_())
    
  • 运行效果同上图。

七、QSplitter

  • QSPlitter,可以动态地拖动子控件之间的边界,可算是动态的布局管理器。
  • QSplitter 对象中各子控件默认是横向布局。
  • QSplitter 类常用方法如下:
    方法 描述
    addWidget() 将小控件添加到 QSplitter 管理器的布局中
    indexOf() 返回小控件在 QSplitter 管理器中的索引
    insertWidget() 根据指定的索引将一个控件插入到 QSplitter 管理器中
    setOrienation() 设置布局方向:Qt.Horizontal,水平方向;Qt.Vertical,垂直方向
    setSize() 设置控件的初始化大小
    count() 返回小控件在 QSplitter 管理器中的数量
  • 示例代码如下:
    # -*- coding:utf-8 -*-
    # Time : 2019/09/04 下午 8:52 
    # Author : 御承扬
    # e-mail:[email protected]
    # project:  PyQt5
    # File : QSplitterRest.py 
    # @software: PyCharm
    
    
    import sys
    from PyQt5.QtWidgets import *
    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    
    
    class WinForm(QWidget):
        def __init__(self):
            super(WinForm, self).__init__()
            self.initUI()
    
        def initUI(self):
            hBox = QHBoxLayout()
            self.setWindowIcon(QIcon("./images/Python2.ico"))
            self.setWindowTitle("QSplitter Demo")
            self.setGeometry(300, 300, 300, 200)
            topLeft = QFrame()
            topLeft.setFrameShape(QFrame.StyledPanel)
            bottom = QFrame()
            bottom.setFrameShape(QFrame.StyledPanel)
            splitter1 = QSplitter(Qt.Horizontal)
            textEdit = QTextEdit()
            splitter1.addWidget(topLeft)
            splitter1.addWidget(textEdit)
            splitter1.setSizes([100, 200])
            splitter2 = QSplitter(Qt.Vertical)
            splitter2.addWidget(splitter1)
            splitter2.addWidget(bottom)
            hBox.addWidget(splitter2)
            self.setLayout(hBox)
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        win = WinForm()
        win.show()
        sys.exit(app.exec_())
    
  • 效果如下:
    PyQt5—布局管理_第8张图片

你可能感兴趣的:(PyQt5)