这是我参与8月更文挑战的第31天,活动详情查看: 8月更文挑战
复习回顾
Python Tkinter 不仅提供多样的组件,还提供管理组件的布局管理器,主要有三种如下:
本期,我们会继续学习Python Tkinter提供第三个布局管理器 Place 相关属性的使用
⏰ 搓搓双手,打起精神,开启我们今天的学习,Let's go~
1. Place 布局管理器概述
Python Tkinter提供的Place 布局管理器,允许使用绝对位置或者相对位置对组件进行排布。
Place 布局管理器特点:
- Place 布局管理器可以通过坐标精确控制组件的位置
- Place 布局管理器排序默认是依次向下排列
- Place 布局管理器可以指定组件的大小
Place 使用场景:
- Place 使用方法灵活,适用于复杂多组件的排布
- Place 使用绝对布局时,需要计算出x和y的参数
- Place 使用相对布局时,需要给出relx,rely,relheight和relwidth参数
2. Place 布局管理器相关属性
| 属性 | 作用 |
|---|---|
| x | 非负数,指定组件的水平偏移位置(像素);同时指定relx选项时,Place会优先计算relx值 |
| y | 非负数,指定组件的垂直偏移位置(像素);同时指定rely选项时,Place会优先计算relx值 |
| bordemode | 指定边框模式,可选值:INSIDE、OUTSIDE |
| height | 非负整数,指定组件的高度 |
| width | 非负整数,指定组件的宽度 |
| relwidth | 指定组件相对于父容器的宽度,取值范围0.0~1.0 |
| relheight | 指定组件相对于父容器的高度,取值范围0.0~1.0 |
| relx | 指定组件相对父容器水平位置,取值范围0.0~1.0 |
| rely | 指定组件相对父容器垂直位置,取值范围0.0~1.0 |
| anchor | 对齐方式,左对齐"W",右对齐"e",顶部对齐"n",底部对齐"s" |
| in_ | 将组件放入指定的组件中。指定组件必现是该父类组件 |
📢 重要说明:
-
Place 采用的坐标方式去管理组件的,X轴向右延伸,Y轴向下延伸
(1) 绝对位置:通过x,y指定组件坐标,单位是pixel(像素)
(2) 相对位置:通过relx,rely指定组件坐标,数值范围为0.0~1.0
(3) 通过x,relx指定坐标值越大,组件的位置越靠右
(4) 通过y,rely指定坐标值越大,组件的位置越靠下
-
anchor属性提供多个值,可以搭配组合使用
组合 含义 NE 靠右上方 SE 靠右下方 SW 靠左下方 NW 靠左上方 N 靠上方 E 靠右方 S 靠下方 W 靠左边 CENTER 居中,默认值
3. Place、Grid 与 Pack属性对照表
| 特点 | Place | pack | Grid |
|---|---|---|---|
| anchor | ✔ | ✔ | |
| sticky | ✔ | ||
| side | ✔ | ||
| ipady | ✔ | ✔ | |
| ipadx | ✔ | ✔ | |
| pady | ✔ | ✔ | |
| padx | ✔ | ✔ | |
| x,y | ✔ | ||
| relx,rely | ✔ | ||
| fill | ✔ | ||
| row | ✔ | ||
| expand | ✔ | ||
| column/columnspan | ✔ | ||
| height/width | ✔ | ||
| relheight/relwidth | ✔ | ||
| in_ | ✔ | ✔ | ✔ |
📢 重要说明:
-
关于组件位置定位处理
(1) Pack 和 Place 都是通过anchor来进行控制的制
(2) Grid则使用sticky在网格中对组件进控
-
关于组件内嵌组件处理
(1)Place、Pack、Grid布局管理器都支持 in_ 属性
-
关于边距处理
(1) Place 使用 relx,rely相对位置来实现内边距概念,x,y实现外边距概念
(2) Pack、Grid则支持使用ipadx,ipady实现内边距,padx,pady实现外边距
4. 小试牛刀
Place 布局管理器练习效果如下:
-
通过如上图分析,首先每张扑克牌是Label组件
- 创建一个以puke1.gif的Label组件
- 使用place布局管理器定位组件位置在(x=10,y=30)
self.photo =PhotoImage(file ="imgs/puke1.gif") self.puke1 =Label(self.master,image = self.photo) self.puke1.place(x=10,y=30)- 测试一张扑克牌的效果
-
我们可以使用for循环推导式来批量创建Label
-
把10张扑克牌的图片放入imgs/目录下
self.photos = [PhotoImage(file= "imgs/puke"+str(i+1)+".gif") for i in range(10)] self.pukes = [Label(self.master,image = self.photos[i]) for i in range(10)] -
-
同理,利用place管理器和for循环批量管理10张图片的排布
for i in range(10): self.pukes[i].place(x=10+i*40,y=30) -
我们可以使用event.widget.winfo_geometry()方法来获取组件的坐标和长宽
print(event.widget.winfo_geometry()) -
我们可以使用event.widget.winfo_y()方法来获取组件的y坐标
print(event.widget.winfo_y()) -
我们可以为每个Label来添加事件,点击label组件位置会上移
-
使用event.widget.winfo_y()方法来获取组件y坐标
-
同时结合逻辑判断语句if...else来判断
-
根据不同的条件,place进行管理组件移到不同的位置上
if event.widget.winfo_y()==30: event.widget.place(y=10) else: event.widget.place(y=30) -
-
对多组的扑克牌label组件添加事件
- 对于列表类型的数据,可以使用bind_class来对其数据进行绑定事件
self.pukes[i].bind_class("Label","<Button-1>",self.choose) -
使用GUI面向对象编程写法,使用Application(Frame)来创建实例对象,创建组件的方法封装给CreateWidgetplace()方法,通过构造函数创建好组件
-
完整代码如下:
from tkinter import * import random class Application(Frame): def __init__(self,master=None): # super()代表的是父类的定义,而不是父类对象 super().__init__(master) self.master = master self.pack() self.CreateWidgetplace() ``` def CreateWidgetplace(self): # self.photo =PhotoImage(file ="imgs/puke1.gif") # self.puke1 =Label(self.master,image = self.photo) # self.puke1.place(x=10,y=30) self.photos = [PhotoImage(file= "imgs/puke"+str(i+1)+".gif") for i in range(10)] self.pukes = [Label(self.master,image = self.photos[i]) for i in range(10)] for i in range(10): self.pukes[i].place(x=10+i*40,y=30) self.pukes[i].bind_class("Label","<Button-1>",self.choose) def choose(self,event): print(event.widget.winfo_geometry()) print(event.widget.winfo_y()) if event.widget.winfo_y()==30: event.widget.place(y=10) else: event.widget.place(y=30) root = Tk() root["background"] = "white" root.geometry('600x270+200+300') root.title("MyfirstAPP") app = Application(master=root) root.mainloop()
总结
本期,我们学习 Python Tkinter 布局管理器Place 相关使用技巧
对比其他两个布局管理器来说,Place 使用的场景更加灵活多变,做出精美界面效果。
但是对于简单的场景来说,place 相较于Pack、Grid 就显着复杂,因此按需选择使用。
以上是本期内容,欢迎大佬们点赞评论指正,下次见~ღ( ´・ᴗ・` )比心🌹🌹