阅读 351

Python Tkinter 布局管理器之Place

玩转Python

这是我参与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属性对照表

特点PlacepackGrid
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 布局管理器练习效果如下:

  1. 通过如上图分析,首先每张扑克牌是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)
    复制代码
    • 测试一张扑克牌的效果

  2. 我们可以使用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)]
    复制代码
  3. 同理,利用place管理器和for循环批量管理10张图片的排布

    for i in range(10):
    
        self.pukes[i].place(x=10+i*40,y=30)
    复制代码
  4. 我们可以使用event.widget.winfo_geometry()方法来获取组件的坐标和长宽

      print(event.widget.winfo_geometry())
    复制代码
  5. 我们可以使用event.widget.winfo_y()方法来获取组件的y坐标

      print(event.widget.winfo_y())
    复制代码
  6. 我们可以为每个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)
    
    复制代码
  7. 对多组的扑克牌label组件添加事件

    • 对于列表类型的数据,可以使用bind_class来对其数据进行绑定事件
    self.pukes[i].bind_class("Label","<Button-1>",self.choose)
    复制代码
  8. 使用GUI面向对象编程写法,使用Application(Frame)来创建实例对象,创建组件的方法封装给CreateWidgetplace()方法,通过构造函数创建好组件

  9. 完整代码如下:

    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 就显着复杂,因此按需选择使用。

以上是本期内容,欢迎大佬们点赞评论指正,下次见~ღ( ´・ᴗ・` )比心🌹🌹

文章分类
后端
文章标签