PyQt5之布局管理

目录

一 写在开头

1.1 本文内容

二 绝对布局

三 布局类

3.1 水平布局(QHBoxLayout)和垂直布局(QVBoxLayout)

3.2 水平布局和垂直布局实例

3.3 网格布局(QGridLayout)

3.4 网格布局实例

3.5 表单布局(QFormLayout)

3.6 表单布局实例

3.7 嵌套布局

3.8 布局管理器QSplitter

注:原创不易,转载请务必注明原作者和出处,感谢支持!

一 写在开头

1.1 本文内容

本文内容为PyQt5中的布局管理。具体内容为:

绝对布局

布局类

水平布局(QHBoxLayout)

垂直布局(QVBoxLayout)

网格布局(QGridLayout)

表单布局(QFormLayout)

嵌套布局

布局管理器QSplitter

二 绝对布局

绝对布局主要用到两个方法,分别是move()和setGeometry()。

#!/usr/bin/env python3# -*- coding: utf-8 -*-

import sys

from PyQt5.QtWidgets import QWidget, QLabel, QApplication

class Window(QWidget):   

def __init__(self):        super().__init__()        self.initUI()            def initUI(self):        lb1 =QLabel('欢迎',self)        lb1.move(15, 10)        lb2 =QLabel('学习',self)        lb2.move(35, 40)        lb3 =QLabel('PyQt5',self)        lb3.move(55, 70)        self.setGeometry(300, 300, 250, 150)        self.setWindowTitle('PyQt5中的绝对定位')        self.show()if __name__ == '__main__':    app =QApplication(sys.argv)    w =Window()    sys.exit(app.exec_())


    <?php

        echo "Hello world!";

    ?>

绝对布局的优点:

可以直接定位每个控件的位置

绝对布局的缺点:

如果改变一个窗口的大小,窗口中控件的大小和位置不会随之改变

所生成的窗口在不同的操作系统下看起来可能不一样

在程序中改变字体时可能会破坏布局

如果修改布局,比如新增一个控件,就必须全部重新布局,既烦琐又费时

三 布局类

3.1 水平布局(QHBoxLayout)和垂直布局(QVBoxLayout)

本小节涉及到的方法及其描述如下:

方法描述

addLayout(self, QLayout, stretch = 0)在窗口中添加布局,stretch为伸缩量,默认为0

addWidget(self, QWidget, stretch, Qt.Alignment alignment)在布局中添加控件,stretch为伸缩量,alignment为对齐方式

addSpacing(self, int)添加伸缩量,具体使用方法见下面的例子

对齐方式Qt.Alignment可能取值有:

参数描述

Qt.AlignLeft水平居左对齐

Qt.AlignRight水平居右对齐

Qt.AlignCenter水平居中对齐

Qt.AlignJustify水平两端对齐

Qt.AlignTop垂直靠上对齐

Qt.AlignBottom垂直靠下对齐

Qt.AlignVCenter垂直居中对齐

3.2 水平布局和垂直布局实例

#!/usr/bin/env python3# -*- coding: utf-8 -*-importsysfromPyQt5.QtWidgetsimportQWidget, QPushButton, QHBoxLayout, QApplicationclassWindow(QWidget):    def __init__(self):        super().__init__()        hbox =QHBoxLayout()        hbox.addWidget(QPushButton(str(1)))        hbox.addWidget(QPushButton(str(2)))        hbox.addWidget(QPushButton(str(3)))        hbox.addWidget(QPushButton(str(4)))        hbox.addWidget(QPushButton(str(5)))        self.setLayout(hbox)        self.setWindowTitle('QHBoxLayout')        self.show()if __name__ == '__main__':    app =QApplication(sys.argv)    w =Window()    sys.exit(app.exec_())

#!/usr/bin/env python3# -*- coding: utf-8 -*-importsysfromPyQt5.QtCoreimportQtfromPyQt5.QtWidgetsimportQWidget, QPushButton, QHBoxLayout, QApplicationclassWindow(QWidget):    def __init__(self):        super().__init__()        hbox =QHBoxLayout()        hbox.addWidget(QPushButton(str(1)), 0,Qt.AlignTop)        hbox.addWidget(QPushButton(str(2)), 0,Qt.AlignTop|Qt.AlignLeft)        hbox.addWidget(QPushButton(str(3)), 0)        hbox.addWidget(QPushButton(str(4)), 0,Qt.AlignLeft|Qt.AlignBottom)        hbox.addWidget(QPushButton(str(5)), 0,Qt.AlignTop)        self.setLayout(hbox)        self.setWindowTitle('水平布局')        self.show()if __name__ == '__main__':    app =QApplication(sys.argv)    w =Window()    sys.exit(app.exec_())

关于addSpacing()的用法见下面的实例。

#!/usr/bin/env python3# -*- coding: utf-8 -*-importsysfromPyQt5.QtWidgetsimportQWidget, QPushButton, QHBoxLayout, QApplicationclassWindow(QWidget):    def __init__(self):        super().__init__()        btn1 =QPushButton()        btn2 =QPushButton()        btn3 =QPushButton()        btn1.setText(str(1))        btn2.setText(str(2))        btn3.setText(str(3))        # addSpacing(1)表示设置伸缩量为1        hbox =QHBoxLayout()        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')        self.show()if __name__ == '__main__':    app =QApplication(sys.argv)    w =Window()    sys.exit(app.exec_())

#!/usr/bin/env python3# -*- coding: utf-8 -*-importsysfromPyQt5.QtWidgetsimportQWidget, QPushButton, QHBoxLayout, QApplicationclassWindow(QWidget):    def __init__(self):        super().__init__()        btn1 =QPushButton()        btn2 =QPushButton()        btn3 =QPushButton()        btn1.setText(str(1))        btn2.setText(str(2))        btn3.setText(str(3))        hbox =QHBoxLayout()        hbox.addStretch(0)        hbox.addWidget(btn1)        hbox.addWidget(btn2)        hbox.addWidget(btn3)        hbox.addStretch(0)        self.setLayout(hbox)        self.setWindowTitle('addStretch')        self.show()if __name__ == '__main__':    app =QApplication(sys.argv)    w =Window()    sys.exit(app.exec_())

3.3 网格布局(QGridLayout)

网格布局需要用到的方法及其描述如下。

方法描述

addWidget(QWidget widget, int row, int col, int alignment = 0)给网格布局添加控件。

widget:要添加的控件

row:位置所在行

col:位置所在列

alignment:对齐方式

addWidget(QWidget widget, int fromRow, int fromColumn, int rowSpan, int columnSpan, int alignment)当所添加的控件跨越多行或多列时,使用这个函数

fromRow:起始行

fromColumn:起始列

rowSpan:控件跨越的行

columnSpan:控件跨越的列

setSpacing(int spacing)设置控件在水平和垂直方向的间隔

3.4 网格布局实例

#!/usr/bin/env python3# -*- coding: utf-8 -*-import sysfrom PyQt5.QtWidgets import QWidget, QGridLayout, QPushButton, QApplicationclassWindow(QWidget):def__init__(self):super().__init__()self.initUI()definitUI(self):        grid = QGridLayout()self.setLayout(grid)        names = ['Cls','Back','','Close','7','8','9','/','4','5','6','*','1','2','3','-','0','.','=','+']        positions = [(i, j)foriinrange(5)forjinrange(4)]forposition, nameinzip(positions, names):ifname =='':                continue            btn = QPushButton(name)            grid.addWidget(btn, *position)self.move(300,150)self.setWindowTitle('网格布局')self.show()if__name__=='__main__':    app = QApplication(sys.argv)    w = Window()    sys.exit(app.exec_())

#!/usr/bin/env python3# -*- coding: utf-8 -*-importsysfromPyQt5.QtWidgetsimportQWidget, QLabel, QLineEdit, QTextEdit, QGridLayout, QApplicationclassWindow(QWidget):    def __init__(self):        super().__init__()        self.initUI()    def initUI(self):        title =QLabel('标题')        author =QLabel('提交人')        review =QLabel('申告内容')        titleEdit =QLineEdit()        authorEdit =QLineEdit()        reviewEdit =QTextEdit()        grid =QGridLayout()        grid.setSpacing(10)        self.setLayout(grid)        grid.addWidget(title, 0, 0)        grid.addWidget(titleEdit, 0, 1)        grid.addWidget(author, 1, 0)        grid.addWidget(authorEdit, 1, 1)        grid.addWidget(review, 2, 0)        grid.addWidget(reviewEdit, 2, 1, 2, 1)        self.setGeometry(300, 300, 350, 300)        self.setWindowTitle('故障申报')        self.show()if __name__ == '__main__':    app =QApplication(sys.argv)    w =Window()    sys.exit(app.exec_())

3.5 表单布局(QFormLayout)

QFormLayout是label-field式的表单布局,顾名思义,就是实现表单方式的布局。表单是提示用户进行交互的一种模式,其主要由两列组成,第一列用于显示信息,给用户提示,一般叫做label域;第二列需要用户进行选择或者输入,一般叫做field域。label与field的关系就是label关联field。

QFormLayout需要用到addRow(label, field)方法。

3.6 表单布局实例

#!/usr/bin/env python3# -*- coding: utf-8 -*-importsysfromPyQt5.QtWidgetsimportQWidget, QFormLayout, QLabel, QLineEdit, QApplicationclassWindow(QWidget):    def __init__(self):        super().__init__()        self.initUI()    def initUI(self):        form =QFormLayout()        lb1 =QLabel('标签1')        le1 =QLineEdit()        lb2 =QLabel('标签2')        le2 =QLineEdit()        lb3 =QLabel('标签3')        le3 =QLineEdit()        form.addRow(lb1,le1)        form.addRow(lb2,le2)        form.addRow(lb3,le3)        self.resize(400, 100)        self.setLayout(form)        self.setWindowTitle('QFormLayout')        self.show()if __name__ == '__main__':    app =QApplication(sys.argv)    w =Window()    sys.exit(app.exec_())

3.7 嵌套布局

所谓嵌套布局就是综合应用上述的布局进行嵌套以完成整体窗口的布局。下面是有关嵌套布局的两个等价实例。注意第二个实例更加简单。

#!/usr/bin/env python3# -*- coding: utf-8 -*-importsysfromPyQt5.QtWidgetsimportQApplication, QWidget, QHBoxLayout, QVBoxLayout, \QGridLayout,QFormLayout,QPushButtonclassWindow(QWidget):    def __init__(self):        super().__init__()        self.setWindowTitle('嵌套布局')        # 全局布局:水平        wlayout =QHBoxLayout()        # 局部布局:水平,垂直,网格,表单        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)))        # 准备4个控件        hwg =QWidget()        vwg =QWidget()        gwg =QWidget()        fwg =QWidget()        # 使用4个控件设置局部布局        hwg.setLayout(hlayout)        vwg.setLayout(vlayout)        gwg.setLayout(glayout)        fwg.setLayout(flayout)        # 将4个控件添加到全局布局中        wlayout.addWidget(hwg)        wlayout.addWidget(vwg)        wlayout.addWidget(gwg)        wlayout.addWidget(fwg)        self.setLayout(wlayout)        self.show()if __name__ == '__main__':    app =QApplication(sys.argv)    w =Window()    sys.exit(app.exec_())

#!/usr/bin/env python3importsysfromPyQt5.QtWidgetsimportQApplication, QWidget, QHBoxLayout, QVBoxLayout, \QGridLayout,QFormLayout,QPushButtonclassWindow(QWidget):    def __init__(self):        super().__init__()        self.setWindowTitle('嵌套布局')        self.resize(700, 200)        # 全局控件(注意参数self),用于承载全局布局        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中添加局部布局        wl.addLayout(hlayout)        wl.addLayout(vlayout)        wl.addLayout(glayout)        wl.addLayout(flayout)        self.show()if __name__ == '__main__':    app =QApplication(sys.argv)    w =Window()    sys.exit(app.exec_())

3.8 布局管理器QSplitter

PyQt提供了一个特殊的布局管理器QSplitter,它可以动态地拖动子控件之间的边界,算是一个动态的布局管理器。

与QSplitter相关的方法及其描述如下。

方法描述

addWidget()将控件添加到QSplitter管理器的布局中

indexOf()返回控件在QSplitter管理器中的索引

insertWidget()根据索引将一个控件插入到QSplitter管理器中

setOrientation()设置布局方法

Qt.Horizontal:水平方向

Qt.Vertical:垂直方向

setSizes()设置控件的初始化大小

count()返回小控件在QSplitter管理器中的数量

#!/usr/bin/env python3importsysfromPyQt5.QtWidgetsimportQWidget, QHBoxLayout, QSplitter, QTextEdit, \QApplication,QFramefromPyQt5.QtCoreimportQtclassWindow(QWidget):    def __init__(self):        super().__init__()        self.initUI()    def initUI(self):        hbox =QHBoxLayout(self)        self.setWindowTitle('QSplitter')        self.setGeometry(300, 300, 300, 200)        topleft =QFrame()        topleft.setFrameShape(QFrame.StyledPanel)        bottom =QFrame()        bottom.setFrameShape(QFrame.StyledPanel)        sp1 =QSplitter(Qt.Horizontal)        te =QTextEdit()        sp1.addWidget(topleft)        sp1.addWidget(te)        sp1.setSizes([100, 200])        sp2 =QSplitter(Qt.Vertical)        sp2.addWidget(sp1)        sp2.addWidget(bottom)        hbox.addWidget(sp2)        self.setLayout(hbox)        self.show()if __name__ == '__main__':    app =QApplication(sys.argv)    w =Window()    sys.exit(app.exec_())

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容