pyqt5教程(五)布局管理

布局管理是GUI编程中的一个重要方面。布局管理是一种如何在应用窗口上防止组件的一种方法。但用 qtdesigner + eric6 会是更方便选择。
我们可以通过两种基础方式来管理布局。我们可以使用绝对定位和布局类。

一、绝对定位

程序指定了组件的位置并且每个组件的大小用像素作为单位来丈量。当你使用了绝对定位,我们需要知道下面的几点限制:

  • 如果我们改变了窗口大小,组件的位置和大小并不会发生改变。
  • 在不同平台上,应用的外观可能不同
  • 改变我们应用中的字体的话可能会把应用弄得一团糟。
  • 如果我们决定改变我们的布局,我们必须完全重写我们的布局,这样非常乏味和浪费时间。
import sys
from PyQt5.QtWidgets import QWidget, QLabel, QApplication
 
 
class Example(QWidget):
     
    def __init__(self):
        super().__init__()
         
        self.my_UI()

    def my_UI(self):
         
        label1 = QLabel('ZetCode', self)
        label1.move(15, 10)
 
        label2 = QLabel('tutorials', self)
        label2.move(35, 40)
         
        label3 = QLabel('for programmers', self)
        label3.move(55, 70)       
         
        self.setGeometry(300, 300, 300, 250)
        self.setWindowTitle('Absolute')   
        self.show()
         
         
if __name__ == '__main__':
     
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

我们使用move()方法来定位我们的组件。在上面的例子中我们使用move()方法定位了一些标签组件。在使用move()方法时,我们给move()方法提供了x和y坐标作为参数。move()使用的坐标系统是从左上角开始计算的。x值从左到右增长。y值从上到下增长。


绝对定位

二、箱布局

布局管理器的布局管理类非常灵活,实用。它是将组件定位在窗口上的首选方式。QHBoxLayout和QVBoxLayout是两个基础布局管理类,他们水平或垂直的线性排列组件。想象一下我们需要在右下角排列两个按钮。为了使用箱布局,我们将使用一个水平箱布局和垂直箱布局来实现。同样为了使用一些必要的空白,我们将添加一些拉伸因子。

import sys
from PyQt5.QtWidgets import (QWidget, QPushButton,
    QHBoxLayout, QVBoxLayout, QApplication)
    #水平布局    垂直布局
 
class Example(QWidget):
     
    def __init__(self):
        super().__init__()
         
        self.my_UI()
         
         
    def my_UI(self):
         
        okButton = QPushButton("确定")
        cancelButton = QPushButton("取消")
 
        hbox = QHBoxLayout()            #创建一个水平箱布局
        hbox.addStretch(1)              #增加了一个拉伸因子
        hbox.addWidget(okButton)        
        hbox.addWidget(cancelButton)    #增加了上面创建的两个按钮
                                        #拉伸因子在两个按钮之前增加了一个可伸缩空间。这会将按钮推到窗口的右边

        vbox = QVBoxLayout()            #为了创建必要的布局,我们把水平布局放置在垂直布局内
        vbox.addStretch(1)
        vbox.addLayout(hbox)            #拉伸因子将把包含两个按钮的水平箱布局推到窗口的底边
         
        self.setLayout(vbox)            #最后,设置一下窗口的主布局
         
        self.setGeometry(300, 300, 300, 150)
        self.setWindowTitle('Buttons')   
        self.show()
         
         
if __name__ == '__main__':
     
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

三、网格布局

最常用的布局类是网格布局。这个布局使用行了列分割空间。要创建一个网格布局,我们需要使用QGridLayout类。

import sys
from PyQt5.QtWidgets import (QWidget, QGridLayout,
    QPushButton, QApplication)
 
 
class Example(QWidget):
     
    def __init__(self):
        super().__init__()
         
        self.my_UI()
         
         
    def my_UI(self):
         
        grid = QGridLayout()            #实例化QGridLayout类
        self.setLayout(grid)            #把这个类设为应用窗口的布局
  

        names = ['Cls', 'Bck', '', '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)   #创建出按钮组件,并使用addWidget()方法向布局中添加按钮
             
        self.move(300, 150)
        self.setWindowTitle('计算器')
        self.show()
         
         
if __name__ == '__main__':
     
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

在我们的例子中,我们创建了一个全是按钮的网格布局。


四、文本审阅窗口示例

在网格中,组件可以跨多列或多行。在这个例子中,我们对它进行一下说明。

import sys
from PyQt5.QtWidgets import (QWidget, QLabel, QLineEdit,
    QTextEdit, QGridLayout, QApplication)
 
 
class Example(QWidget):
     
    def __init__(self):
        super().__init__()
         
        self.my_UI()
         
         
    def my_UI(self):
         
        title = QLabel('Title')
        author = QLabel('Author')
        review = QLabel('Review')
 
        titleEdit = QLineEdit()
        authorEdit = QLineEdit()
        reviewEdit = QTextEdit()
 
        grid = QGridLayout()        #创建一个网格布局
        grid.setSpacing(10)         #设置组件之间的间距
        
        grid.addWidget(title, 1, 0)
        grid.addWidget(titleEdit, 1, 1)
 
        grid.addWidget(author, 2, 0)
        grid.addWidget(authorEdit, 2, 1)
 
        grid.addWidget(review, 3, 0)
        grid.addWidget(reviewEdit, 3, 1, 5, 1)
                  #向网格布局中增加一个组件,可以提供组件的跨行和跨列参数
                  #在这个例子中,我们让reviewEdit组件跨了5行。
         
        self.setLayout(grid)        #把类设为应用窗口的布局 放前放后好像都行
         
        self.setGeometry(300, 300, 350, 300)
        self.setWindowTitle('Review')   
        self.show()
         
         
if __name__ == '__main__':
     
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

我们创建了包含三个标签,两个单行编辑框和一个文本编辑框组件的窗口。布局使用了QGridLayout布局。


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

推荐阅读更多精彩内容