布局说白了就是将如何将组件放到我们想要的位置上,即组件如何摆放的问题
1.move()方法布局
1.是什么
简单点就是给定组件的坐标,来放置窗口中的组件
我们先来简单了解一下PyQt的坐标体系,原点坐标是(0,0)位于左上角
2.案例代码
import sys
from PyQt5.QtWidgets import *
class Window(QWidget):
def __init__(self):
super(Window, self).__init__()
self.resize(200, 200) # 1
label_1 = QLabel('Label 1', self)
label_2 = QLabel('Label 2', self)
label_1.move(-20, 0) #注释2开始
label_2.move(50, 100) #注释2结束
if __name__ == '__main__':
app = QApplication([])
window = Window()
window.show()
sys.exit(app.exec())
(#1) 调用resize()方法将窗口大小设置为宽200像素,长200像素。
(#2) 调用move()方法分别设置两个QLabel控件的位置。窗口的左上角为坐标原点(0, 0),QLabel1控件的坐标为(−20, 0)意味着控件还往原点左侧移动了一些,这样的话一部分文本就会被遮住
3.缺点
(1)当控件数量很多时,该方法就不再方便了。
因为我们要计算很多个坐标,而且万一其中一个控件的位置要改变,就可能会影响其他所有控件的位置,牵一发而动全身的方法是不推荐的。
(2)使用move()方法还有一个弊端——坐标都是固定的。
也就是说,当我们拉伸窗口时,控件的位置固定不变,并不能够自适应。
2.垂直布局管理器QVBoxLayout
1.是什么
简单点就是将控件从上到下垂直进行摆放,我们可以用QVBoxLayout这个布局管理器来实现,如图所示
2.案例代码
import sys
from PyQt5.QtWidgets import *
class Window(QWidget):
def __init__(self):
super(Window, self).__init__()
username = QLabel('Username:') #注释1开始
password = QLabel('Password:') #注释1结束
v_layout = QVBoxLayout() #注释2开始
v_layout.addWidget(username)
v_layout.addWidget(password)
self.setLayout(v_layout) #注释2结束
if __name__ == '__main__':
app = QApplication([])
window = Window()
window.show()
sys.exit(app.exec())
(#1) 实例化两个QLabel控件,将其文本设置为“Username:”和“Password:”。
(#2) 实例化一个垂直布局管理器,并通过**addWidget()**方法将两个控件依次添加到布局中。接着调用窗口的setLayout()方法将垂直布局方式设置为窗口的整体布局。
在垂直布局中,先添加的控件位于后添加的控件上方
3.水平布局管理器QHBoxLayout
1.是什么
简单点就是将控件从左到右依次摆放,控件都是水平对齐的,我们可以用QHBoxLayout这个布局管理器来实现,如结构图
2.案例代码
import sys
from PyQt5.QtWidgets import *
class Window(QWidget):
def __init__(self):
super(Window, self).__init__()
username_label = QLabel('Username:') #注释1开始
username_line = QLineEdit() #注释1结束
h_layout = QHBoxLayout() #注释2开始
h_layout.addWidget(username_label)
h_layout.addWidget(username_line)
self.setLayout(h_layout) #注释2结束
if __name__ == '__main__':
app = QApplication([])
window = Window()
window.show()
sys.exit(app.exec())
(#1) 除了Qlabel控件,我们还添加了QLineEdit控件,它是一个单行文本输入框,在这里用于输入账号。
(#2) 实例化一个水平布局管理器并调用addWidget()方法将QLabel控件和QLineEdit控件添加到布局中。接着通过窗口的setLayout()方法将水平布局方式设置为窗口的整体布局。
在水平布局中,先添加的控件位于后添加的控件左侧
4.表单布局管理器QFormLayout
1.是什么?
简单点就是将控件按照表单的样式进行布局,比如可以将控件以一行两列的形式进行布局。
常用于如下情况
表单布局管理器通常用来设置文本型控件和输入型控件(比如QLabel和QLineEdit)的布局,通常左列控件为文本型控件,右列控件为输入型控件。
2.案例代码
使用该布局管理器可以帮助我们快速实现一个登录界面
import sys
from PyQt5.QtWidgets import *
class Window(QWidget):
def __init__(self):
super(Window, self).__init__()
username_label = QLabel('Username:') # 注释1开始
password_label = QLabel('Password:')
username_line = QLineEdit()
password_line = QLineEdit() # 注释1结束
f_layout = QFormLayout() # 注释2开始
f_layout.addRow(username_label, username_line)
f_layout.addRow(password_label, password_line)
self.setLayout(f_layout) # 注释2结束
if __name__ == '__main__':
app = QApplication([])
window = Window()
window.show()
sys.exit(app.exec())
(#1) 实例化两个QLabel控件和两个QLineEdit控件,这两个QLineEdit控件分别用来输入账号和密码。
(#2) 实例化一个表单布局管理器,然后调用addRow()方法添加Qlabel控件和QLineEdit控件。这样username_label和username_line就处在第一行,password_label和password_line就处在第二行。左列控件为QLabel,右列控件为QLineEdit。
5.网格布局管理器QGridLayout
1.是什么
使用网格布局(Grid Layout)管理器时,我们可以把窗口想象成是带有网格的,如下图所示,而这些网格都有相应的坐标
从图中我们可以得到以下信息。
(1)username_label文本控件被放到了第1行、第1列,网格坐标为(0, 0)。
(2)username_line输入框控件被放到了第1行、第2列,网格坐标为(0, 1)。
(3)password_label文本控件被放到了第2行、第1列,网格坐标为(1, 0)。
(4)password_line输入框控件被放到了第2行、第2列,网格坐标为(1, 1)。
网格坐标只在网格布局管理器中使用,与之前讲的窗口坐标无关。另外,网格坐标是用0表示第1行或者第1列的。
2.案例代码
import sys
from PyQt5.QtWidgets import *
class Window(QWidget):
def __init__(self):
super(Window, self).__init__()
username_label = QLabel('Username:')
password_label = QLabel('Password:')
username_line = QLineEdit()
password_line = QLineEdit()
g_layout = QGridLayout() # 注释1开始
g_layout.addWidget(username_label, 0, 0)
g_layout.addWidget(username_line, 0, 1)
g_layout.addWidget(password_label, 1, 0)
g_layout.addWidget(password_line, 1, 1)
self.setLayout(g_layout) # 注释1结束
if __name__ == '__main__':
app = QApplication([])
window = Window()
window.show()
sys.exit(app.exec())
(#1) 网格布局管理器同样有addWidget()方法,我们在调用该方法时还需要传入控件的网格坐标。
6.布局嵌套
1.是什么
简单点就是布局管理器除了可以添加控件,还可以添加子布局。
以我们登录界面为例
第一种布局的嵌套
通过图1-19我们可以看出,username_label和username_line使用水平布局,password_label和password_line也使用水平布局,这两个水平布局被包含在一个垂直布局中,即在QVBoxLayout中添加了两个QHBoxLayout。
第二种布局的嵌套
通过图1-20我们可以看出,username_label和password_label使用垂直布局,username_line和password_line也使用垂直布局,这两个垂直布局被包含在一个水平布局中,即在QHBoxLayout中添加了两个QVBoxLayout
2.案例代码
第一种布局实现的登录界面
import sys
from PyQt5.QtWidgets import *
class Window(QWidget):
def __init__(self):
super(Window, self).__init__()
username_label = QLabel('Username:')
password_label = QLabel('Password:')
username_line = QLineEdit()
password_line = QLineEdit()
v_layout = QVBoxLayout() # 注释1开始
h1_layout = QHBoxLayout()
h2_layout = QHBoxLayout()
h1_layout.addWidget(username_label)
h1_layout.addWidget(username_line)
h2_layout.addWidget(password_label)
h2_layout.addWidget(password_line)
v_layout.addLayout(h1_layout)
v_layout.addLayout(h2_layout)
self.setLayout(v_layout) # 注释1结束
if __name__ == '__main__':
app = QApplication([])
window = Window()
window.show()
sys.exit(app.exec())
(#1) 实例化一个垂直布局管理器和两个水平布局管理器。
h1_layout水平布局管理器中添加了username_label和username_line控件,
h2_layout水平布局管理器中则添加了password_label和password_line控件。
最后v_layout垂直布局管理器调用addLayout()方法依次添加两个水平布局管理器,使它们从上到下垂直排列。