PyQt5学习记录(3)---布局管理

时间:2020-12-14 23:03:33

布局管理的两种方法

布局管理是所有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()

效果:

PyQt5学习记录(3)---布局管理

注意:绝对定位通过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()

效果:
PyQt5学习记录(3)---布局管理

要点提示

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

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

对应效果:

PyQt5学习记录(3)---布局管理

如果将设置拉伸因子的函数去掉,则添加的两个按钮平分空间,占满整个布局就是这个效果了:
PyQt5学习记录(3)---布局管理

网格布局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()

效果如下:
PyQt5学习记录(3)---布局管理

核心提示

  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()

效果图:

PyQt5学习记录(3)---布局管理

要点提示

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.