python 控件 相对布局_四、PyQt5布局管理(绝对&相对、水平、垂直、格栅、表单)...

目录

一、绝对布局

二、盒布局

三、格栅布局

四、格栅布局跨行跨列显示

布局管理即设置窗体上各个控件的位置,对于新手来说,这是学习的难点。

布局管理根据绝对坐标是否变动分为绝对布局和相对布局两大类。采用相对布局的窗口在变大或缩小时,各控件的位置关系会保持固定比例做相应变动。而采用绝对布局的窗口变动时,空间位置不会变动。

而相对布局根据方式不同,又可以分为水平布局(QHBoxLayout)、垂直布局管理(QVBoxLayout)、栅格布局管理(QGridLayout)、表单布局管理(QFormLayout)。

一、绝对布局

绝对布局中以像素为单位区分元素的位置,衡量元素的大小,以设定坐标的方式精准的定位每个控件的位置,但是这种布局方式也有缺点:

窗体控件无法根据窗口的位置和大小而变化;

改变字体大小时可能会破坏布局;

当分辨率有较大改变时,原有布局会破坏;

在设计阶段,如果需要添加或删除控件,如果要调整控件位置,就需要全部调整。

下面是绝对布局的示例:

1 importsys,os2 from PyQt5.QtWidgets importQWidget,QLabel,QApplication3 from PyQt5.QtGui importQIcon4

5 path = os.path.dirname(os.path.dirname( os.path.dirname(__file__)))6

7 classMyWindow(QWidget):8

9 def __init__(self):10 super(MyWindow, self).__init__()11 self.initUI()12

13 definitUI(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 lbl2.move(150,150)23

24

25 if __name__ == '__main__':26 app =QApplication(sys.argv)27 win =MyWindow()28 win.show()29 sys.exit(app.exec_())

绝对布局示例

效果图如下:

根据效果图可以发现:

在改变窗口长和宽的时候,两个标签的位置不会变动;

两个标签用不同的方法创建。第一个标签不仅设定了位置,还固定了大小,所以内容不能完全展示。

二、盒布局(Box Layout)

采用盒布局的窗口在改变窗体大小时,各控件会按相应比例自动调整。代码如下:

1 importsys,os2 from PyQt5.QtWidgets importQApplication,QHBoxLayout,QVBoxLayout,QWidget,QPushButton3 from PyQt5.QtGui importQIcon4

5 path = os.path.dirname(os.path.dirname( os.path.dirname(__file__)))6

7 classMyWindow(QWidget):8

9 def __init__(self):10 super(MyWindow, self).__init__()11 self.initUI()12

13 definitUI(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

32 if __name__ == '__main__':33 app =QApplication(sys.argv)34 win =MyWindow()35 win.show()36 sys.exit(app.exec_())

盒布局示例

盒布局中使用stretch函数在布局中增加了一个伸缩量,里面的参数表示QSpacerItem的个数,默认值为零(也可以理解为除去控件外,空白部分所占的比例),会将你放在layout中的空间压缩成默认的大小。而且在窗体缩小时,这个伸缩量也可以变小,直至为零。

“确认”和“取消”两个按钮出现在窗体右下角。示例中实现的方法是首先创建一个垂直布局,按钮上部伸缩量占比为1,接着把这整个布局放在水平布局里,伸缩量占比为1.于是实现了给出的显示效果。

下面对addstretch方法做个补充讲解:

1 importsys,os2 from PyQt5.QtWidgets importQApplication,QHBoxLayout,QVBoxLayout,QWidget,QPushButton3 from PyQt5.QtGui importQIcon4

5 path = os.path.dirname(os.path.dirname( os.path.dirname(__file__)))6

7 classMyWindow(QWidget):8

9 def __init__(self):10 super(MyWindow, self).__init__()11 self.initUI()12

13 definitUI(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

36 if __name__ == '__main__':37 app =QApplication(sys.argv)38 win =MyWindow()39 win.show()40 sys.exit(app.exec_())

addstretch方法示例

使用addstretch方法分别给定了参数1、2、3,即在水平布局上,除去按钮部分外的空白区域,按照1:2:3的比例分配空间。下过如下图所示。

三、格栅布局

格栅布局是最常用的布局方式,下面我们通过模拟计算器界面的方式来学习格栅布局。

1 importsys,os2 from PyQt5.QtWidgets importQApplication,QPushButton,QWidget,QGridLayout3 from PyQt5.QtGui importQIcon4

5 path = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))6

7 classMyWindow(QWidget):8

9 def __init__(self):10 super(MyWindow, self).__init__()11 self.initUI()12

13 definitUI(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)28 for position,name inzip(positions,names):29 button =QPushButton(name)30 grid.addWidget(button,*position)31

32

33

34 if __name__ == '__main__':35 app =QApplication(sys.argv)36 win =MyWindow()37 win.show()38 sys.exit(app.exec_())

格栅布局示例

显示效果如下:

下面来分析代码

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','-',

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

显示效果如下:

[('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))]

四、格栅布局跨行跨列显示

虽然格栅布局最常用,但是实际窗口的控件往往是大小不一的,单个控件跨行跨列很常见,下面来介绍下跨行跨列的情况。

1 importsys,os2 from PyQt5.QtWidgets importQWidget,QPushButton,QLabel,QLineEdit,QApplication,QGridLayout3 from PyQt5.QtGui importQIcon, QPixmap4

5 path = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))6

7 classMyWindow(QWidget):8

9 def __init__(self):10 super().__init__()11 self.initUI()12

13 definitUI(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

42 if __name__ == '__main__':43 app =QApplication(sys.argv)44 win =MyWindow()45 win.show()46 sys.exit(app.exec_())

跨行跨列示例

显示效果如下:

下面来分析代码:

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)为设置控件之间的左右间距。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值