2种布局方法:
addLayout() 插入子布局, addWidget() 插入控件
4种布局方式对应4个布局类:
水平布局类(QHBoxLayout),可以把所添加的控件在水平方向上依次排列。
垂直布局类(QVBoxLayout),可以把所添加的控件在垂直方向上依次排列。
网格布局类(QGridLayout),可以把所添加的控件以网格的形式排列。
表单布局类(QFormLayout),可以把所添加的控件以两列的形式排列。
绝对位置布局
代码示例
import sys
from PyQt5.QtWidgets import QWidget, QLabel, QApplication
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
lbl1 = QLabel('欢迎', self)
lbl1.move(15, 10)
lbl2 = QLabel('学习', self)
lbl2.move(35, 40)
lbl3 = QLabel('PyQt5 !', self)
lbl3.move(55, 70)
self.setGeometry(300, 300, 320, 120)
self.setWindowTitle('绝对位置布局例子')
if __name__ == '__main__':
app = QApplication(sys.argv)
demo = Example()
demo.show()
sys.exit(app.exec_())
绝对位置布局的优点如下
●可以直接定位每个控件的位置。
绝对位置布局的缺点如下
●如果改变一个窗口的大小,窗口中控件的大小和位置不会随之改变。
●所生成的窗口在不同的操作系统下看起来可能不一样。
●在程序中改变字体时可能会破坏布局。
●如果修改布局,比如新增一个控件,就必须全部重新布局,既烦琐又费时。
QBoxLayout(框布局)
QHBoxLayout (水平布局)
常用方法
addLayout(self, QLayout, stretch = 0) | 在窗口的右边添加布局,使用stretch(伸缩量)进行伸缩,伸缩量默认为0 |
addWidget(self, QWidget, stretch, Qt.Alignment alignment) | 在布局中添加控件: stretch (伸缩量),只适用于QBoxLayout,控件和窗口 会随着伸缩量的变大而增大 alignment,指定对齐的方式 |
addSpacing(self, int) | 设置各控件的上下间距,通过该方法可以增加额外的空间 |
对齐参数
Qt.AlignLeft | 水平方向居左对齐 |
Qt.AlignRight | 水平方向居右对齐 |
Qt.QtAlignCenter | 水平方向居中对齐 |
Qt.AlignJustify | 水平方向两端对齐 |
Qt.AlignTop | 垂直方向靠上对齐 |
Qt.AlignBottom | 垂直方向靠下对齐 |
Qt.AlignVCenter | 垂直方向居中对齐 |
代码示例1
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QPushButton
from PyQt5.QtCore import Qt
class Winform(QWidget):
def __init__(self, parent=None):
super(Winform, self).__init__(parent)
self.setWindowTitle("水平布局管理例子")
self.resize(800, 200)
# 水平布局按照从左到右的顺序进行添加按钮部件。
hlayout = QHBoxLayout()
# 水平居左 垂直居上
hlayout.addWidget(QPushButton(str(1)), 0, Qt.AlignLeft | Qt.AlignTop)
hlayout.addWidget(QPushButton(str(2)), 0, Qt.AlignLeft | Qt.AlignTop)
hlayout.addWidget(QPushButton(str(3)))
# 水平居左 垂直居下
hlayout.addWidget(QPushButton(str(4)), 0, Qt.AlignLeft | Qt.AlignBottom)
hlayout.addWidget(QPushButton(str(5)), 0, Qt.AlignLeft | Qt.AlignBottom)
self.setLayout(hlayout)
if __name__ == "__main__":
app = QApplication(sys.argv)
form = Winform()
form.show()
sys.exit(app.exec_())
代码示例2
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QPushButton
from PyQt5.QtCore import Qt
class Winform(QWidget):
def __init__(self, parent=None):
super(Winform, self).__init__(parent)
self.setWindowTitle("水平布局管理例子")
# 水平布局按照从左到右的顺序进行添加按钮部件。
hlayout = QHBoxLayout()
hlayout.addWidget(QPushButton(str(1)))
hlayout.addWidget(QPushButton(str(2)))
hlayout.addWidget(QPushButton(str(3)))
hlayout.addWidget(QPushButton(str(4)))
hlayout.addWidget(QPushButton(str(5)))
# 设置控件间的间距
hlayout.setSpacing(0)
self.setLayout(hlayout)
if __name__ == "__main__":
app = QApplication(sys.argv)
form = Winform()
form.show()
sys.exit(app.exec_())
QVBoxLayout (垂直布局)
代码示例
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton
class Winform(QWidget):
def __init__(self, parent=None):
super(Winform, self).__init__(parent)
self.setWindowTitle("垂直布局管理例子")
self.resize(330, 150)
# 垂直布局按照从上到下的顺序进行添加按钮部件。
vlayout = QVBoxLayout()
vlayout.addWidget(QPushButton(str(1)))
vlayout.addWidget(QPushButton(str(2)))
vlayout.addWidget(QPushButton(str(3)))
vlayout.addWidget(QPushButton(str(4)))
vlayout.addWidget(QPushButton(str(5)))
self.setLayout(vlayout)
if __name__ == "__main__":
app = QApplication(sys.argv)
form = Winform()
form.show()
sys.exit(app.exec_())
addStretch()
QBoxLayout.addStretch (int stretch =0)
addStretch()函数在布局管理器中增加一个可伸缩的控件(QSpaceltem),0为最小值,并且将stretch作为伸缩量添加到布局末尾stretch参数表示均分的比例,默认值为0
代码示例
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QPushButton
import sys
class WindowDemo(QWidget):
def __init__(self):
super().__init__()
btn1 = QPushButton(self)
btn2 = QPushButton(self)
btn3 = QPushButton(self)
btn1.setText('button 1')
btn2.setText('button 2')
btn3.setText('button 3')
hbox = QHBoxLayout()
# 设置伸缩量为1
hbox.addStretch(1)
hbox.addWidget(btn1)
# 设置伸缩量为1
hbox.addStretch(1)
hbox.addWidget(btn2)
# 设置伸缩量为1
hbox.addStretch(1)
hbox.addWidget(btn3)
# 设置伸缩量为1
hbox.addStretch(1)
self.setLayout(hbox)
self.setWindowTitle("addStretch 例子")
if __name__ == "__main__":
app = QApplication(sys.argv)
win = WindowDemo()
win.show()
sys.exit(app.exec_())
QGridLayout(网格布局)
QGridLayout(网格布局)是将窗口分隔成行和列的网格来进行排列。通常可以使用函数addWidget()将被管理的控件(Widget)添加到窗口中,或者使用addLayout()函数将布局(Layout)添加到窗口中。也可以通过addWidget()函数对所添加的控件设置行数和列数的跨越,最后实现网格占据多个窗格。
addWidget ( QWidget widget, int row, int col, int alignment=0) | 给网格布局添加控件,设置指定的行列,起始位置(top-left position)的默认值是(0,0)。 widget:所添加的控件 row:控件的行数,默认从0开始 column:控件的列数,默认从0开始 alignment:对齐方式 |
addWidger(QWidget widget, int fromRow, int fromColumn, int rowSpan, int columnSpan, Qt.Alignment alignment = 0) | 所添加的控件跨越很多行或者列时,使用这个函数。 widget:所添加的控件 fromRow:控件的起始行数 fromColumn:控件的起始列数 rowSpan:控件跨越的行数 columnSpan:控件跨越的列数 alignment:对齐方式 |
setSpacing ( int spacing) | 设置控件在水平和垂直方向的间隔 |
代码示例1
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QGridLayout, QPushButton
class Winform(QWidget):
def __init__(self, parent=None):
super(Winform, self).__init__(parent)
self.initUI()
def initUI(self):
# 创建QGridLayout的实例,并设置为窗口的布局
grid = QGridLayout()
self.setLayout(grid)
# 创建按钮的标签列表
names = ['cls', 'Back', '', 'Close',
'7', '8', '9', '/',
'4', '5', '6', '*',
'1', '2', '3', '-',
'0', '.', '=', '+']
# 在网格中创建一个位置列表
positions = [(i, j) for i in range(5) for j in range(4)]
# 创建按钮,并通过addWidget()方法添加到布局中
for position, name in zip(positions, names):
if name == '':
continue
button = QPushButton(name)
grid.addWidget(button, *position)
self.move(300, 150)
self.setWindowTitle('网格布局管理例子')
if __name__ == "__main__":
app = QApplication(sys.argv)
form = Winform()
form.show()
sys.exit(app.exec_())
代码示例2
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QGridLayout, QLabel, QLineEdit, QTextEdit
class Winform(QWidget):
def __init__(self, parent=None):
super(Winform, self).__init__(parent)
self.initUI()
def initUI(self):
title = QLabel('标题')
author = QLabel('提交人')
review = QLabel('申告内容')
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)
self.setLayout(grid)
self.setGeometry(300, 300, 350, 300)
self.setWindowTitle('故障申告')
if __name__ == "__main__":
app = QApplication(sys.argv)
form = Winform()
form.show()
sys.exit(app.exec_())
QFormLayout(表单布局)
代码示例
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QFormLayout, QLineEdit, QLabel
class Winform(QWidget):
def __init__(self, parent=None):
super(Winform, self).__init__(parent)
self.setWindowTitle("窗体布局管理例子")
self.resize(400, 100)
fromlayout = QFormLayout()
labl1 = QLabel("标签1")
lineEdit1 = QLineEdit()
labl2 = QLabel("标签2")
lineEdit2 = QLineEdit()
labl3 = QLabel("标签3")
lineEdit3 = QLineEdit()
fromlayout.addRow(labl1, lineEdit1)
fromlayout.addRow(labl2, lineEdit2)
fromlayout.addRow(labl3, lineEdit3)
self.setLayout(fromlayout)
if __name__ == "__main__":
app = QApplication(sys.argv)
form = Winform()
form.show()
sys.exit(app.exec_())
嵌套布局
在布局中添加其他布局
代码示例
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QVBoxLayout, QGridLayout, QFormLayout, QPushButton
class MyWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('嵌套布局示例')
# 全局布局(1个):水平
wlayout = QHBoxLayout()
# 局部布局(4个):水平、竖直、网格、表单
hlayout = QHBoxLayout()
vlayout = QVBoxLayout()
glayout = QGridLayout()
formlayout = 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)
formlayout.addWidget(QPushButton(str(9)))
formlayout.addWidget(QPushButton(str(10)))
formlayout.addWidget(QPushButton(str(11)))
formlayout.addWidget(QPushButton(str(12)))
# 准备四个部件
hwg = QWidget()
vwg = QWidget()
gwg = QWidget()
fwg = QWidget()
# 四个部件设置局部布局
hwg.setLayout(hlayout)
vwg.setLayout(vlayout)
gwg.setLayout(glayout)
fwg.setLayout(formlayout)
# 四个部件加至全局布局
wlayout.addWidget(hwg)
wlayout.addWidget(vwg)
wlayout.addWidget(gwg)
wlayout.addWidget(fwg)
# 窗体本体设置全局布局
self.setLayout(wlayout)
if __name__ == "__main__":
app = QApplication(sys.argv)
win = MyWindow()
win.show()
sys.exit(app.exec_())
在控件中添加布局
代码示例
from PyQt5.QtWidgets import *
import sys
class MyWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('嵌套布局示例')
self.resize(700, 200)
# 全局部件(注意参数 self),用于"承载"全局布局
wwg = QWidget(self)
# 全局布局(注意参数 wwg)
wl = QHBoxLayout(wwg)
hlayout = QHBoxLayout()
vlayout = QVBoxLayout()
glayout = QGridLayout()
formlayout = 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)
formlayout.addWidget(QPushButton(str(9)))
formlayout.addWidget(QPushButton(str(10)))
formlayout.addWidget(QPushButton(str(11)))
formlayout.addWidget(QPushButton(str(12)))
# 这里向局部布局内添加部件,将他加到全局布局
wl.addLayout(hlayout)
wl.addLayout(vlayout)
wl.addLayout(glayout)
wl.addLayout(formlayout)
if __name__ == "__main__":
app = QApplication(sys.argv)
win = MyWindow()
win.show()
sys.exit(app.exec_())
QSplitter
QSplitter可以动态地拖动子控件之间的边界,算是一个动态的布局管理器。QSplitter 允许用户通过拖动子控件的边界来控制子控件的大小,并提供了一个处理拖曳子控件的控制器。
在QSplitter对象中各子控件默认是横向布局的,可以使用Qt.Vertical进行垂直布局。
常用方法
addWidget() | 将小控件添加到QSplitter管理器的布局中 |
indexOf() | 返回小控件在QSplitter管理器中的索引 |
insertWidget() | 根据指定的索引将一个控件插入到QSlitter管理器中 |
setOrientation() | 设置布局方向: Qt.Horizontal,水平方向 Qt.Vertical,垂直方向 |
setSizes() | 设置控件的初始化大小 |
count() | 返回小控件在QSplitter管理器中的数量 |
代码示例
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class SplitterExample(QWidget):
def __init__(self):
super(SplitterExample, self).__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)
splitter1 = QSplitter(Qt.Horizontal)
textedit = QTextEdit()
splitter1.addWidget(topleft)
splitter1.addWidget(textedit)
splitter1.setSizes([100, 200])
splitter2 = QSplitter(Qt.Vertical)
splitter2.addWidget(splitter1)
splitter2.addWidget(bottom)
hbox.addWidget(splitter2)
self.setLayout(hbox)
if __name__ == '__main__':
app = QApplication(sys.argv)
demo = SplitterExample()
demo.show()
sys.exit(app.exec_())