PyQt5学习记录---布局管理

Posted yanzi1225627

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PyQt5学习记录---布局管理相关的知识,希望对你有一定的参考价值。

布局管理的两种方法

布局管理是所有GUI编程中核心内容之一。在Qt里有两种方法可以控制布局,分别是绝对定位和布局类.

绝对定位

代码:

#coding=utf-8
import sys
from PyQt5.QtWidgets import QWidget, QLabel, QApplication

class Example1(QWidget):

    def __init__(self):
        super().__init__()
        self.initUI()
        pass

    def initUI(self):
        label1 = QLabel('第一个', self)
        label1.move(15, 10)

        label2 = QLabel('第2个', self)
        label2.move(35, 40)

        label3 = QLabel('第3个', self)
        label3.move(55, 70)

        self.setGeometry(300, 300, 450, 450)
        self.setWindowTitle('绝对定位示例')
        self.show()

        pass

def main1():
    app = QApplication(sys.argv)
    example1 = Example1()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main1()

效果:

注意:绝对定位通过move函数进行,相对于父widget的左上角为原点.

箱布局

箱布局是我们进行布局的首选,核心就是QHBoxLayoutQVBoxLayout。这两个类继承自QBoxLayout,而QBoxLayout又继承自QLayout,QLayout继承自QObjectQLayoutItem.

#coding=utf-8
import sys
from PyQt5.QtWidgets import QWidget, QLabel, QApplication, QPushButton, QHBoxLayout, \\
    QVBoxLayout

class Example2(QWidget):

    def __init__(self):
        super().__init__()
        self.initUI()
        pass

    def initUI(self):
        okBtn = QPushButton('OK')
        cancelBtn = QPushButton('Cancel')

        hbox = QHBoxLayout()
        hbox.addStretch(1)
        hbox.addWidget(okBtn)
        hbox.addWidget(cancelBtn)

        vbox = QVBoxLayout()
        vbox.addStretch(1)
        vbox.addLayout(hbox)

        self.setLayout(vbox)

        self.setGeometry(300, 300, 450, 450)
        self.setWindowTitle('箱布局')
        self.show()
        pass

def main2():
    app = QApplication(sys.argv)
    example2 = Example2()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main2()

效果:

要点提示

只有一点,那就是addStretch()函数的理解,它为widget增加一个拉伸因子,至于是怎么拉伸跟父布局有关。如上面代码,就是先拉伸,再添加两个button,所有button会被挤到最右侧。如果我们先添加两个button,再添加这个因子,效果就是这样:

 hbox = QHBoxLayout()
 hbox.addWidget(okBtn)
 hbox.addWidget(cancelBtn)
 hbox.addStretch(1)

对应效果:

如果将设置拉伸因子的函数去掉,则添加的两个按钮平分空间,占满整个布局就是这个效果了:

网格布局QGridLayout

该类继承自QLayout,也是用的很多。这个可以回想web的布局,早些年一直是表格布局当道。
下面看个计算器的例子:

#coding=utf-8
import sys
from PyQt5.QtWidgets import QWidget, QLabel, QApplication, QPushButton, QHBoxLayout, \\
    QVBoxLayout, QGridLayout

class Example3(QWidget):

    def __init__(self):
        super().__init__()
        self.initUI()
        pass

    def initUI(self):

        grid = QGridLayout()
        self.setLayout(grid)
        names = ['cls', 'bck', '', 'close',
                 '7', '8', '9', '/',
                 '4', '5', '6', '*',
                 '1', '2', '3', '-',
                 '0', '.', '=', '+']
        poses = [(i, j) for i in range(5) for j in range(4)]

        for pos, name in zip(poses, names):
            if name == '':
                continue
            btn = QPushButton(name)
            grid.addWidget(btn, *pos)



        self.setGeometry(300, 300, 450, 450)
        self.setWindowTitle('网格布局--计算器')
        self.show()
        pass

def main3():
    app = QApplication(sys.argv)
    example3 = Example3()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main3()

效果如下:

核心提示

  1. zip的使用http://www.cnblogs.com/frydsh/archive/2012/07/10/2585370.html
  2. *pos的含义,在没有*的时候pos就是(0, 0)是个元组,加个星号之后成了0, 0两个int。

QGridLayout加强

QGridLayout还可以设置每个item占多个列,即不均匀分配.

#coding=utf-8
import sys
from PyQt5.QtWidgets import QWidget, QLabel, QApplication, QPushButton, QHBoxLayout, \\
    QVBoxLayout, QGridLayout, QLineEdit, QTextEdit

class Example4(QWidget):

    def __init__(self):
        super().__init__()
        self.initUI()
        pass

    def initUI(self):

        title = QLabel('Title')
        author = QLabel('Author')
        review = QLabel('Review')

        titleEdit = QLineEdit()
        authorEdit = QLineEdit()
        reviewEdit = QTextEdit()

        grid = QGridLayout()
        grid.setSpacing(30)

        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, 5, 1)




        self.setLayout(grid)
        self.setGeometry(300, 300, 450, 450)
        self.setWindowTitle('网格布局--文本审阅窗口')
        self.show()
        pass

def main4():
    app = QApplication(sys.argv)
    example4 = Example4()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main4()

效果图:

要点提示

1.addWidget的原型

void QGridLayout::addLayout(QLayout *layout, int row, int column, Qt::Alignment alignment = Qt::Alignment())

Places the layout at position (row, column) in the grid. The top-left position is (0, 0).

The alignment is specified by alignment. The default alignment is 0, which means that the widget fills the entire cell.

A non-zero alignment indicates that the layout should not grow to fill the available space but should be sized according to sizeHint().

layout becomes a child of the grid layout

第二个参数是行号,第三个坐标是列号。默认左上角为(0, 0)。

2.addWidget的第二种:

void QGridLayout::addWidget(QWidget *widget, int fromRow, int fromColumn, int rowSpan, int columnSpan, Qt::Alignment alignment = Qt::Alignment())

This is an overloaded function.

This version adds the given widget to the cell grid, spanning multiple rows/columns. The cell will start at fromRow, fromColumn spanning rowSpan rows and columnSpan columns. The widget will have the given alignment.

If rowSpan and/or columnSpan is -1, then the widget will extend to the bottom and/or right edge, respectively.

以上是关于PyQt5学习记录---布局管理的主要内容,如果未能解决你的问题,请参考以下文章

python3 PyQt5 运行后界面控件缩在左上角,但在QTdesigner里面预览是正常的?

PyQt5快速入门PyQt5布局管理

学习进度总结

PyQt5学习--基本窗口控件--QMainWindow

《PyQT5软件开发》第3章 PyQt5布局管理

《PyQT5软件开发 - 基础篇》第3章 PyQt5布局管理