博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PyQt5—布局管理
阅读量:3935 次
发布时间:2019-05-23

本文共 14048 字,大约阅读时间需要 46 分钟。

布局管理

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:2923616405@qq.com# project:  PyQt5# File : AbsolutePositionTest.py # @software: PyCharmimport sysfrom PyQt5.QtGui import QIconfrom PyQt5.QtWidgets import QWidget, QLabel, QApplicationclass 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_())
  • 效果如下:
    在这里插入图片描述

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:2923616405@qq.com# project:  PyQt5# File : HBoxLayoutTest.py # @software: PyCharmimport sysfrom 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)
    在这里插入图片描述
  • 设置控件之间的间距,使用 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:2923616405@qq.com# project:  PyQt5# File : VBoxLayoutTest.py # @software: PyCharmimport sysfrom 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:2923616405@qq.com# project:  PyQt5# File : StretchTest01.py # @software: PyCharmimport sysfrom 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_())
  • 效果如下:
    在这里插入图片描述
  • 如果在第一个控件之前添加伸缩控件,那么所有的控件都会居右显示;反之,如果在最后一个控件之后添加伸缩控件,呢么所有的孔家都会居左显示。

四、网格布局

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

1、单一的网格单元格

  • 示例代码如下:
    # -*- coding:utf-8 -*-# Time : 2019/09/01 下午 3:51 # Author : 御承扬# e-mail:2923616405@qq.com# project:  PyQt5# File : GridLayoutTesto1.py # @software: PyCharmimport sysfrom 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_())
  • 效果如下:
    在这里插入图片描述

2、跨越行列式单元网格

  • 除了一个网格一个控件,还可以一个控件占据多个行列,示例代码如下:
    # -*- coding:utf-8 -*-# Time : 2019/09/02 下午 2:28 # Author : 御承扬# e-mail:2923616405@qq.com# project:  PyQt5# File : GridLayoutTest02.py # @software: PyCharmimport sysfrom 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_())
  • 效果如下:
    在这里插入图片描述

五、表单布局

  • 表单布局,QFormLayout,实现 label-field 式表单布局的布局控件,主要有两列构成:信息提示区域和信息输入区域,前者也叫 label 域,后者也叫 field 域。
  • 示例代码如下:
    # -*- coding:utf-8 -*-# Time : 2019/09/03 下午 4:15 # Author : 御承扬# e-mail:2923616405@qq.com# project:  PyQt5# File : formLayoutTest.py # @software: PyCharmimport sysfrom 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 的各种布局综合起来使用,不在单独使用某种布局。主要方法有往布局中添加布局和往控件中添加布局。

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

  • 将使用的多种布局中,选择某一个或更多作为全局布局,其余作为该全局布局的子布局,示例代码如下:
    # -*- coding:utf-8 -*-# Time : 2019/09/03 下午 7:49 # Author : 御承扬# e-mail:2923616405@qq.com# project:  PyQt5# File : nestLayout01.py # @software: PyCharmimport sysfrom 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_())
  • 效果如下:
    在这里插入图片描述

2、在控件中添加布局

  • 不同于上一种方式中,四种布局需要四种空白控件,这一种方式可以做到无论有多少中布局方式,只需要一个空白控件,示例代码如下:
    # -*- coding:utf-8 -*-# Time : 2019/09/03 下午 8:23 # Author : 御承扬# e-mail:2923616405@qq.com# project:  PyQt5# File : nestLayout02.py # @software: PyCharmimport sysfrom 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:2923616405@qq.com# project:  PyQt5# File : QSplitterRest.py # @software: PyCharmimport sysfrom 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_())
  • 效果如下:
    在这里插入图片描述

转载地址:http://ltqgn.baihongyu.com/

你可能感兴趣的文章
uninstall software on ubuntu
查看>>
install kinnect senor on ubuntu
查看>>
calibrate kinnect v1 on ubuntu
查看>>
flann中关于数据的stride
查看>>
cv::Mat ptr 和 at 注意事项
查看>>
cuda更新过后, findcuda找不到怎么办?
查看>>
cast shared_ptr to shared_ptr
查看>>
Elastic Job入门示例-实现DataflowJob接口
查看>>
Elastic Job入门示例-Console控制台
查看>>
Elastic Job入门示例-实现原理介绍
查看>>
HTTP状态码对照表
查看>>
Spring Cloud Feign 服务间调用 -超时
查看>>
MySQL 中事务、事务隔离级别详解
查看>>
Telnet 命令在Windows与Linux/Unix下的区别
查看>>
Java传统IO / NIO基础知识
查看>>
Netty3- 入门示例
查看>>
Netty3 - 多连接的客户端示例
查看>>
Netty3 -会话状态监听
查看>>
Netty3 - 对象的序列化与反序列化ProtoBuf
查看>>
Netty3 - 对象的序列化与反序列化 java
查看>>