四、PyQt5布局管理(绝对相对、⽔平、垂直、格栅、表单)
⽬录
⼀、绝对布局
⼆、盒布局
三、格栅布局
四、格栅布局跨⾏跨列显⽰
布局管理即设置窗体上各个控件的位置,对于新⼿来说,这是学习的难点。
布局管理根据绝对坐标是否变动分为绝对布局和相对布局两⼤类。采⽤相对布局的窗⼝在变⼤或缩⼩时,各控件的位置关系会保持固定⽐例做相应变动。⽽采⽤绝对布局的窗⼝变动时,空间位置不会变动。
⽽相对布局根据⽅式不同,⼜可以分为⽔平布局(QHBoxLayout)、垂直布局管理(QVBoxLayout)、栅格布局管理(QGridLayout)、表单布局管理(QFormLayout)。⼀、绝对布局
绝对布局中以像素为单位区分元素的位置,衡量元素的⼤⼩,以设定坐标的⽅式精准的定位每个控件的位
置,但是这种布局⽅式也有缺点:
窗体控件⽆法根据窗⼝的位置和⼤⼩⽽变化;
改变字体⼤⼩时可能会破坏布局;
当分辨率有较⼤改变时,原有布局会破坏;
在设计阶段,如果需要添加或删除控件,如果要调整控件位置,就需要全部调整。
下⾯是绝对布局的⽰例:
1import sys,os
2from PyQt5.QtWidgets import QWidget,QLabel,QApplication
3from PyQt5.QtGui import QIcon
4
5 path = os.path.dirname(os.path.dirname( os.path.dirname(__file__)))
6
7class MyWindow(QWidget):
8
9def__init__(self):
10 super(MyWindow, self).__init__()
11 self.initUI()
12
13def initUI(self):
14 self.setGeometry(300,300,500,400)
15 self.setWindowIcon(QIcon(r'%s\4.图标素材\chuan.ico' % path))
16 self.setWindowTitle('绝对布局⽰例')
17
18 lbl1 = QLabel('这是第⼀个标签',self)
19 lbl1.setGeometry(80,80,30,30)
20
21 lbl2 = QLabel('这是第⼆个标签',self)
22 ve(150,150)
23
24
25if__name__ == '__main__':
26 app = QApplication(sys.argv)
27 win = MyWindow()
28 win.show()
29 _())
绝对布局⽰例
效果图如下:
根据效果图可以发现:
1. 在改变窗⼝长和宽的时候,两个标签的位置不会变动;
2. 两个标签⽤不同的⽅法创建。第⼀个标签不仅设定了位置,还固定了⼤⼩,所以内容不能完全展⽰。
⼆、盒布局(Box Layout)
采⽤盒布局的窗⼝在改变窗体⼤⼩时,各控件会按相应⽐例⾃动调整。代码如下:
1import sys,os
2from PyQt5.QtWidgets import QApplication,QHBoxLayout,QVBoxLayout,QWidget,QPushButton
3from PyQt5.QtGui import QIcon
4
5 path = os.path.dirname(os.path.dirname( os.path.dirname(__file__)))
6
7class MyWindow(QWidget):
8
9def__init__(self):
10 super(MyWindow, self).__init__()
11 self.initUI()
12
13def initUI(self):
14 self.setGeometry(300,300,500,400)
15 self.setWindowIcon(QIcon(r'%s/4.图标素材/chuan.ico' % path))
16 self.setWindowTitle('盒布局⽰例')
17
18 okbutton = QPushButton('确认') #设置“确认”按钮
19 cancelbutton = QPushButton('取消') #设置“取消”按钮
20
21 hbox = QHBoxLayout() #布局实例化对象
22 hbox.addStretch(1) #设置分配⽐例
23 hbox.addWidget(okbutton) #添加“确认”按钮到窗体
24 hbox.addWidget(cancelbutton)
25
26 vbox = QVBoxLayout()
27 vbox.addStretch(1)
28 vbox.addLayout(hbox)
29
30 self.setLayout(vbox) #设置窗体布局
31
32if__name__ == '__main__':
33 app = QApplication(sys.argv)
34 win = MyWindow()
35 win.show()
36 _())
盒布局⽰例
盒布局中使⽤stretch函数在布局中增加了⼀个伸缩量,⾥⾯的参数表⽰QSpacerItem的个数,默认值为
零(也可以理解为除去控件外,空⽩部分所占的⽐例),会将你放在layout 中的空间压缩成默认的⼤⼩。⽽且在窗体缩⼩时,这个伸缩量也可以变⼩,直⾄为零。
“确认”和“取消”两个按钮出现在窗体右下⾓。⽰例中实现的⽅法是⾸先创建⼀个垂直布局,按钮上部伸缩量占⽐为1,接着把这整个布局放在⽔平布局⾥,伸缩量占⽐为1.于是实现了给出的显⽰效果。
下⾯对addstretch⽅法做个补充讲解:
1import sys,os
2from PyQt5.QtWidgets import QApplication,QHBoxLayout,QVBoxLayout,QWidget,QPushButton
3from PyQt5.QtGui import QIcon
4
5 path = os.path.dirname(os.path.dirname( os.path.dirname(__file__)))
6
7class MyWindow(QWidget):
8
9def__init__(self):
10 super(MyWindow, self).__init__()
11 self.initUI()
12
13def initUI(self):
14 self.setGeometry(300,300,500,300)
15 self.setWindowIcon(QIcon(r'%s/4.图标素材/chuan.ico' % path))
16 self.setWindowTitle('addstrtch⽰例')
17
18 fir_button = QPushButton('按钮⼀') #设置按钮⼀
19 sec_button = QPushButton('按钮⼆') #设置按钮⼆
20 thir_button = QPushButton('按钮三') #设置按钮三
21
22 hbox = QHBoxLayout()
23 hbox.addStretch(1)
24 hbox.addWidget(fir_button)
25 hbox.addStretch(2)
26 hbox.addWidget(sec_button)
27 hbox.addStretch(3)
28 hbox.addWidget(thir_button)
29
30# vbox = QVBoxLayout()
31# vbox.addStretch(1)
32# vbox.addLayout(hbox)
33
34 self.setLayout(hbox) #设置窗体布局
35
36if__name__ == '__main__':
37 app = QApplication(sys.argv)
38 win = MyWindow()
39 win.show()
40 _())
addstretch⽅法⽰例
使⽤addstretch⽅法分别给定了参数1、2、3,即在⽔平布局上,除去按钮部分外的空⽩区域,按照1:2:3的⽐例分配空间。下过如下图所⽰。
三、格栅布局
格栅布局是最常⽤的布局⽅式,下⾯我们通过模拟计算器界⾯的⽅式来学习格栅布局。
1import sys,os
2from PyQt5.QtWidgets import QApplication,QPushButton,QWidget,QGridLayout
3from PyQt5.QtGui import QIcon
4
5 path = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
6
7class MyWindow(QWidget):
8
9def__init__(self):
10 super(MyWindow, self).__init__()
11 self.initUI()
12
13def initUI(self):
14 self.setWindowTitle('格栅布局⽰例')
15 self.setWindowIcon(QIcon(r'%s\4.图标素材\chuan.ico' % path))
16 self.setGeometry(600,300,500,400)
17
18 names = ['On','Off','AC','/',
19'7','8','9','*',
20'4','5','6','-',
21'1','2','3','+',
22'0','00','.','=']
23
24 positions = [(i,j) for i in range(5) for j in range(4)]
25
26 grid = QGridLayout()
27 self.setLayout(grid)
28for position,name in zip(positions,names):
29 button = QPushButton(name)
30 grid.addWidget(button,*position)
31
32
33
34if__name__ == '__main__':
35 app = QApplication(sys.argv)
36 win = MyWindow()
37 win.show()
38 _())
格栅布局⽰例
显⽰效果如下:
下⾯来分析代码
names = ['On','Off','AC','/',
'7','8','9','*',
'4','5','6','-',
'1','2','3','+',
'0','00','.','=']
names列表是各按键的名称。
positions = [(i,j) for i in range(5) for j in range(4)]
这个列表⽣成式⽣成的列表类似⼀个矩阵,各元素的数值恰好是按钮在格栅布局中位置
for position,name in zip(positions,names):
button = QPushButton(name)
grid.addWidget(button,*position)
这⾥使⽤的zip函数。python3中为了减少内存,zip函数返回的是⼀个对象。如果要展⽰列表,可通过 list() 转换。
names = ['On','Off','AC','/',
'7','8','9','*',
'4','5','6','-',
printform'1','2','3','+',
'0','00','.','=']
positions = [(i,j) for i in range(5) for j in range(4)]
a = zip(names,positions)
print(a)
print(list(a))
显⽰效果如下:
<zip object at 0x0000020EFF489508>
[('On', (0, 0)), ('Off', (0, 1)), ('AC', (0, 2)), ('/', (0, 3)), ('7', (1, 0)), ('8', (1, 1)), ('9', (1, 2)), ('*', (1, 3)), ('4', (2, 0)), ('5', (2, 1)), ('6', (2, 2)), ('-', (2, 3)), ('1', (3, 0)), ('2', (3, 1)), ('3', (3, 2)), ('+', (3, 3)), ('0', (4, 0)), ('00', (4, 1)), ('.', (4, 2)), ('=', (4, 3))] 四、格栅布局跨⾏跨列显⽰
虽然格栅布局最常⽤,但是实际窗⼝的控件往往是⼤⼩不⼀的,单个控件跨⾏跨列很常见,下⾯来介绍下跨⾏跨列的情况。
1import sys,os
2from PyQt5.QtWidgets import QWidget,QPushButton,QLabel,QLineEdit,QApplication,QGridLayout
3from PyQt5.QtGui import QIcon, QPixmap
4
5 path = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
6
7class MyWindow(QWidget):
8
9def__init__(self):
10 super().__init__()
11 self.initUI()
12
13def initUI(self):
14 self.setWindowTitle('跨⾏跨列布局⽰例')
15 self.setWindowIcon(QIcon(r'%s\4.图标素材\chuan.ico' % path))
16 self.setGeometry(600,300,450,300)
17
18 lbl_image = QLabel()
19 png = QPixmap(r'%s\4.图标素材\cartoon1.ico' % path)
20 lbl_image.setPixmap(png)
21 lbl_image.setScaledContents(True) #图⽚⾃适应标签⼤⼩
22
23 lbl_user = QLabel('账号:') #设置标签
24 lbl_pwd = QLabel('密码:')
25 okbutton = QPushButton('确认') #设置按钮
26 cancelbutton = QPushButton('取消')
27 lineedit_user = QLineEdit() #设置单⾏⽂本框
28 lineedit_pwd = QLineEdit()
29
30 grid = QGridLayout()
31 self.setLayout(grid)
32 grid.setSpacing(10) #间距为10
33
34 grid.addWidget(lbl_image,1,1,3,1)
35 grid.addWidget(lineedit_user,1,2,1,2)
36 grid.addWidget(lineedit_pwd,2,2,1,2)
37 grid.addWidget(lbl_user,1,4)
38 grid.addWidget(lbl_pwd,2,4)
39 grid.addWidget(okbutton,3,2,1,1)
40 grid.addWidget(cancelbutton,3,3,1,1)
41
42if__name__ == '__main__':
43 app = QApplication(sys.argv)
44 win = MyWindow()
45 win.show()
46 _())
跨⾏跨列⽰例
显⽰效果如下:
下⾯来分析代码:
grid.addWidget(lbl_image,1,1,3,1)
addwidget⽅法第⼀个参数是添加的控件对象,后⾯的(1,1)表⽰位置坐标为(1,1),即控件左上⾓坐标为(1,1)。这⾥的1并不是以像素为单位,⽽是以⾏和列为单
位,(1,1)即第⼀⾏第⼀列。最后的(3,1)意思是这个控件占三⾏1列。下⾯⽤表格和图⽚来表⽰布局⽅式
图⽚
(3⾏1列)单⾏⽂本框1“账号”标签单⾏⽂本框2“密码”标签“确认”按钮“取消”按钮
grid.setSpacing(10)
即各控件之间的上下间距为10(以像素为单位)。同理还有grid.setMargin(int)为设置控件之间的左右间距。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论