《快速掌握PyQt5》第三章 布局管理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/La_vie_est_belle/article/details/82346289

第三章 布局管理

3.1 垂直布局QVBoxLayout

3.2 水平布局QHBoxLayout

3.3 混合使用QVBoxLayout和QHBoxLayout

3.4 网格布局QGridLayout

3.5 小结


把各个控件摆摆好,让整个界面更加有序好看,这就是布局管理器的作用。

3.1 垂直布局QVBoxLayout

该布局方式就是将各个控件按从上到下垂直的方式摆放,下面看一个例子:

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QVBoxLayout


class Demo(QWidget):

    def __init__(self):
        super(Demo, self).__init__()
        self.user_label = QLabel('Username:', self)
        self.pwd_label = QLabel('Password:', self)

        self.v_layout = QVBoxLayout()                   # 1
        self.v_layout.addWidget(self.user_label)        # 2
        self.v_layout.addWidget(self.pwd_label)         # 3

        self.setLayout(self.v_layout)                   # 4


if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())

1. 实例化一个垂直布局管理器QVBoxLayout;

2-3. 通过调用addWidget()方法来将控件一个个添加到垂直布局中,最先添加的出现在最上方;

4. 将self.v_layout设为整个窗口的最终布局方式。

运行截图如下,可以看出两个标签文本是垂直对齐排列的:

3.2 水平布局QHBoxLayout

将控件从左到右依次水平摆放:

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QLineEdit, QHBoxLayout


class Demo(QWidget):

    def __init__(self):
        super(Demo, self).__init__()
        self.user_label = QLabel('Username:', self)
        self.user_line = QLineEdit(self)                # 1

        self.h_layout = QHBoxLayout()                   # 2
        self.h_layout.addWidget(self.user_label)        # 3
        self.h_layout.addWidget(self.user_line)         # 4

        self.setLayout(self.h_layout)                   # 5


if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())

1. QLineEdit控件就是一个用来进行单行文本输入的框;

2. 实例化一个水平布局管理器;

3-4. 将QLabel和QLineEdit控件添加到水平布局管理器中,先添加的出现在左边;

5. 将self.h_layout设为整个窗口的最终布局方式。

运行截图如下:

3.3 混合使用QVBoxLayout和QHBoxLayout

我们将实现一个用于输入账号密码,并有登陆和注册按钮的小窗口:

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QLineEdit, QPushButton, \
    QHBoxLayout, QVBoxLayout


class Demo(QWidget):

    def __init__(self):
        super(Demo, self).__init__()

        self.user_label = QLabel('Username:', self)
        self.pwd_label = QLabel('Password:', self)
        self.user_line = QLineEdit(self)
        self.pwd_line = QLineEdit(self)
        self.login_button = QPushButton('Log in', self)
        self.signin_button = QPushButton('Sign in', self)

        self.label_v_layout = QVBoxLayout()                      # 1
        self.line_v_layout = QVBoxLayout()                       # 2
        self.button_h_layout = QHBoxLayout()                     # 3
        self.label_line_h_layout = QHBoxLayout()                 # 4
        self.all_v_layout = QVBoxLayout()                        # 5

        self.label_v_layout.addWidget(self.user_label)           # 6
        self.label_v_layout.addWidget(self.pwd_label)
        self.line_v_layout.addWidget(self.user_line)
        self.line_v_layout.addWidget(self.pwd_line)
        self.button_h_layout.addWidget(self.login_button)
        self.button_h_layout.addWidget(self.signin_button)
        self.label_line_h_layout.addLayout(self.label_v_layout)  # 7
        self.label_line_h_layout.addLayout(self.line_v_layout)
        self.all_v_layout.addLayout(self.label_line_h_layout)
        self.all_v_layout.addLayout(self.button_h_layout)

        self.setLayout(self.all_v_layout)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())

1-3. 实例化三个布局管理器分别用来管理QLabel,QLineEdit和QPushButton;

4-5. 这两个布局管理器用来管理1-3中的布局,它们添加的不是QLabel、QLineEdit或者QPushButton控件,而是通过addLayout()方法添加布局管理器。第4行的水平布局管理器将self.label_v_layout垂直布局和self.line_vlayout垂直布局这两个布局管理器从左到右依次水平摆放。第5行的垂直布局管理器将self.label_line_h_layout和self.button_h_layout垂直从上到下摆放;

6-7. 添加控件用addWidght(),添加布局用addLayout()。

运行截图如下:

上面的代码是将两个QLabel用垂直布局方式摆放,将两个QLineEdit也用垂直布局方式摆放,最后用一个水平布局管理来摆放着两个垂直布局管理器。那换种思路,可以把QLabel和QLineEdit用水平布局方式摆放:

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QLineEdit, QPushButton, \
    QHBoxLayout, QVBoxLayout


class Demo(QWidget):

    def __init__(self):
        super(Demo, self).__init__()

        self.user_label = QLabel('Username:', self)
        self.pwd_label = QLabel('Password:', self)
        self.user_line = QLineEdit(self)
        self.pwd_line = QLineEdit(self)
        self.login_button = QPushButton('Log in', self)
        self.signin_button = QPushButton('Sign in', self)

        self.user_h_layout = QHBoxLayout()                      
        self.pwd_h_layout = QHBoxLayout()                       
        self.button_h_layout = QHBoxLayout()                     
        self.all_v_layout = QVBoxLayout()                        

        self.user_h_layout.addWidget(self.user_label)
        self.user_h_layout.addWidget(self.user_line)
        self.pwd_h_layout.addWidget(self.pwd_label)
        self.pwd_h_layout.addWidget(self.pwd_line)
        self.button_h_layout.addWidget(self.login_button)
        self.button_h_layout.addWidget(self.signin_button)
        self.all_v_layout.addLayout(self.user_h_layout)
        self.all_v_layout.addLayout(self.pwd_h_layout)
        self.all_v_layout.addLayout(self.button_h_layout)

        self.setLayout(self.all_v_layout)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())

相比而言,这种布局方式更加清晰明了。

3.4 网格布局QGridLayout

当使用该布局管理器的时候,你可以把整个窗体想象成带有坐标的,然后只用把各个控件放在相应的坐标就好了,请看示例(还是上方的登录框):

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QLineEdit, QPushButton, \
    QGridLayout, QVBoxLayout, QHBoxLayout


class Demo(QWidget):

    def __init__(self):
        super(Demo, self).__init__()

        self.user_label = QLabel('Username:', self)
        self.pwd_label = QLabel('Password:', self)
        self.user_line = QLineEdit(self)
        self.pwd_line = QLineEdit(self)
        self.login_button = QPushButton('Log in', self)
        self.signin_button = QPushButton('Sign in', self)

        self.grid_layout = QGridLayout()                                # 1
        self.h_layout = QHBoxLayout()
        self.v_layout = QVBoxLayout()

        self.grid_layout.addWidget(self.user_label, 0, 0, 1, 1)         # 2
        self.grid_layout.addWidget(self.user_line, 0, 1, 1, 1)
        self.grid_layout.addWidget(self.pwd_label, 1, 0, 1, 1)
        self.grid_layout.addWidget(self.pwd_line, 1, 1, 1, 1)
        self.h_layout.addWidget(self.login_button)                     
        self.h_layout.addWidget(self.signin_button)
        self.v_layout.addLayout(self.grid_layout)                       # 3
        self.v_layout.addLayout(self.h_layout)                          # 4

        self.setLayout(self.v_layout)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())

这里混合使用QVBoxLayout、QHBoxLayout和QGridLayout来完成布局。

1. 实例化一个QGridLayout布局管理器

2. QGridLayout的addWidget()方法遵循如下语法形式:

addWidget(widget, row, column, rowSpan, columnSpan)

widget就是要添加的控件;row为第几行,0代表第一行;column为第几列,0代表第一列;rowSpan表示要让这个控件去占用几行(默认一行);columnSpan表示要让这个控件去占用几列(默认一列)。

在上方程序中,我们将self.user_label放在(0, 0)这个坐标,也就是第一行第一列,占用一行一列;将self.user_line放在(0, 1),即第一行第二列,也就是self.user_label的右边,占用一行一列;将self.pwd_label放在(1, 0),即第二行第一列,在self.user_label的正下方,占用一行一列;最后我们将self.pwd_line放在(1, 1),即第二行第二列,占用一行一列。

因为默认都是一行一列,所以也可以写成:

self.grid_layout.addWidget(self.user_label, 0, 0)        
self.grid_layout.addWidget(self.user_line, 0, 1)
self.grid_layout.addWidget(self.pwd_label, 1, 0)
self.grid_layout.addWidget(self.pwd_line, 1, 1)

3-4. 最后,程序用垂直布局管理器将一个网格布局和一个水平布局添加进去。

当然你也可以尝试单单用QGridLayout来完成这次界面的布局,但是你会发现效果并不会让人很满意,可以自行去试一下。

合理的运用这三种布局方式可以在程序设计上事半功倍。

3.5 小结

1. QTextEdit控件为单行文本输入框;

2.. 了解三种布局方式:垂直布局QVBoxLayout、水平布局QHBoxLayout和网格布局QGridLayout;

3. addWidget()方法用来添加控件,addLayout()方法用来添加布局;

4. 请记住QGridLayout的addWidget()语法形式:

addWidget(widget, row, column, rowSpan, columnSpan)

----------------------------------------------------------------------

喜欢的小伙伴可以加入这个Python QQ交流群一起学习:820934083

猜你喜欢

转载自blog.csdn.net/La_vie_est_belle/article/details/82346289
今日推荐