原文链接

    学习python的tkinter免不了要对各个组件进行位置的排放与设定,常用的布局管理器有grid,pack和place。这三种均用于同一父组件下的组件布局,但是也是有区别的,先看下他们各自的含义吧。

    pack:按添加顺序排列组件

    grid:按行列形式排列组件

    place:允许程序员指定组件的大小和位置


    常用方法:这里先列出来,后文会对个方法进行说明

    1. **pack常用的方法**
    2. pack(**options)
    3. pack_configure(**options)
    4. pack_forget()
    5. pack_info()
    6. pack_propagate(flag)
    7. pack_slaves()
    8. **grid常用方法**
    9. grid(**options)
    10. grid_bbox(column=None, row=None, col2=None, row2=None)
    11. grid_columnconfigure(index, **options)
    12. grid_configure(**options)
    13. grid_forget()
    14. grid_info()
    15. grid_location(x, y)
    16. grid_propagate(flag)
    17. grid_remove()
    18. grid_rowconfigure(index, **options)
    19. grid_size()
    20. grid_slaves(row=None, column=None)
    21. **place常用方法**
    22. place(**options)
    23. place_configure(**options)
    24. place_forget()
    25. place_info()
    26. place_slaves()
    27. slaves()

    使用说明

    pack管理器使用:

    pack适合于少量的组件排序,所以在使用上是相当简单,一般添加组件后直接使用.pack()方法即可。。但是如果想要对复杂的组件进行布局,那就要使用grid()或者Frame框架。

    注:同一个父组件中不能同时使用pack()和grid(),否则Tkinter会一直纠结先用哪个布局管理器,所以就卡死在纠结中了。

    先来看个例子吧,是经常要用到的情况:将一个组件放到一个容器组件中,并填充整个父组件。

    1. 1 from tkinter import *
    2. 2 root = Tk()
    3. 3 listbox = Listbox(root)
    4. 4 listbox.pack(fill=BOTH,expand=True) #fill选项是填充整个父组件,expand选项是拉伸时依旧填满
    5. 5 for i in range(10):
    6. 6 listbox.insert(END,str(i))
    7. 7 mainloop()

    执行结果:

    Tkinter 的三大布局管理器 pack、grid 和 place用法汇总 - 图1
    其中,fill 选项是告诉窗口管理器该组件将填充整个分配给它的空间,BOTH 表示同时横向和纵向扩展,X 表示横向,Y 表示纵向。expand
    选项是告诉窗口管理器将父组件的额外空间也充满

    默认下,pack 是将添加的组件一次纵向排列

    1. 1 from tkinter import *
    2. 2 root = Tk()
    3. 3 Label(root,text="red",bg="red",fg="white").pack(fill=X) #fill选项是设置横向填充
    4. 4 Label(root,text="red",bg="green",fg="black").pack(fill=X)
    5. 5 Label(root,text="red",bg="blue",fg="white").pack(fill=X)
    6. 6
    7. 7 # Label(root,text="red",bg="red",fg="white").pack(side=RIGHT)#如果想将组件整体横向排序,可以设置side选择
    8. 8 mainloop()

    执行结果:

    Tkinter 的三大布局管理器 pack、grid 和 place用法汇总 - 图2
    grid管理器的使用

    grid 管理器可以说是 Tkinter 这三个布局管理器中最灵活多变的。如果你只希望学习使用一个布局管理器,那么 grid
    绝对是首选。当你在设计对话框的时候,使用 grid 尤其便捷。使用一个 grid 就可以简单的实现你用很多个框架和 pack 搭建起来的效果。

    使用 grid 排列组件,只要告诉它你想要组件放置的位置(行 / 列,row 选项指定行,column 选项指定列)。此外你并不用提前指出网格(grid
    分布给组件的位置称为网格)的尺寸,因为管理器会自动计算。

    来看一个简单的登录界面:

    1. 1 from tkinter import *
    2. 2 root = Tk()
    3. 3 Label(root,text="用户名:").grid(row=0,column=0)
    4. 4 Label(root,text="密 码:").grid(row=1,column=0)
    5. 5
    6. 6 Entry(root).grid(row=0,column=1)
    7. 7 Entry(root,show="*").grid(row=1,column=1)
    8. 8 mainloop()

    执行结果:

    Tkinter 的三大布局管理器 pack、grid 和 place用法汇总 - 图3
    用几个网格来放置一个组件,可以使用 rowspan 和columnspan 实现跨行跨列的功能

    1. 1 from tkinter import *
    2. 2
    3. 3 root = Tk()
    4. 4
    5. 5 Label(root, text="用户名").grid(row=0, sticky=W)
    6. 6 Label(root, text="密码").grid(row=1, sticky=W)
    7. 7
    8. 8 photo = PhotoImage(file="gaga.png")
    9. 9 Label(root, image=photo).grid(row=0, column=2, rowspan=2, padx=5, pady=5)
    10. 10 #rowspan选项设置了跨行,现在photo组件可以显示0,1两行了。padx,pady设置了边距,使图片文字不挨在一起11 Entry(root).grid(row=0, column=1)
    11. 12 Entry(root, show="*").grid(row=1, column=1)
    12. 13
    13. 14 Button(root,text="提交", width=10).grid(row=2, columnspan=3, pady=5)
    14. 15
    15. 16 root.mainloop()

    执行结果:

    Tkinter 的三大布局管理器 pack、grid 和 place用法汇总 - 图4
    place 管理器使用

    通常情况下不建议使用 place 布局管理器,因为对比起 pack 和 grid,place 要做更多的工作。不过存在即合理,place
    在一些特殊的情况下可以发挥妙用,甚至是 pack 和 grid 无法代替。

    将子组件显示在父组件的正中间

    1. 1 from tkinter import *
    2. 2
    3. 3 root = Tk()
    4. 4 def callback():
    5. 5 print('真的点到我了')
    6. 6 Button(root, text='点我呀', command=callback).place(relx=0.5, rely=0.5, anchor=CENTER) #relx和rely是相对父组件的位置。0是最左边,0.5是正中间,1是最右边
    7. 7 mainloop()

    执行结果:

    Tkinter 的三大布局管理器 pack、grid 和 place用法汇总 - 图5
    在某种情况下,你希望一个组件能够覆盖另一个组件。下面使用一个按钮覆盖一个Label图片的例子

    1. 1 from tkinter import *
    2. 2
    3. 3 root = Tk()
    4. 4 photo = PhotoImage(file="gaga.png")
    5. 5 Label(root, image=photo).pack()
    6. 6 def callback():
    7. 7 print('点到我了')
    8. 8 Button(root, text='点我', command=callback).place(relx=0.5, rely=0.5, anchor=CENTER) #relx和rely是相对父组件的位置,范围是 00~1.0。0是最左边,0.5是正中间,1是最右边
    9. 9 mainloop()

    执行结果:

    Tkinter 的三大布局管理器 pack、grid 和 place用法汇总 - 图6
    relheight 和 relwidth 选项则是指定相对于父组件的尺寸

    1. 1 from tkinter import *
    2. 2
    3. 3 root = Tk()
    4. 4
    5. 5 Label(root, bg='red').place(relx=0.5, rely=0.5, relheight=0.75, relwidth=0.75, anchor=CENTER) #relheight和relwidth是设置调用place的子组件相对于父组件的高度和宽度
    6. 6 Label(root, bg='yellow').place(relx=0.5, rely=0.5, relheight=0.5, relwidth=0.75, anchor=CENTER)
    7. 7 Label(root, bg='green').place(relx=0.5, rely=0.5, relheight=0.25, relwidth=0.75, anchor=CENTER)
    8. 8
    9. 9 mainloop()

    执行结果:

    Tkinter 的三大布局管理器 pack、grid 和 place用法汇总 - 图7
    还有 x 和 y 选项用于设置偏移(像素),如果同时设置 relx(rely) 和 x(y),那么 place 将优先计算 relx 和
    rely,然后再实现 x 和 y 指定的偏移值。


    pack的方法

    注:下面方法适用于所有组件

    pack(**options) —下方详细列举了各个选项的具体含义和用法

    | 选项 | 含义 | | —- | —- | | anchor | —控制组件在pack分配的空间中的位置
    —N, NE, E, SE, S, SW, W, NW或CENTER来定位(EWSN表示东南西北)
    —默认值是CENTER | | expand | —指定是否填充父组件的额外空间
    —默认值是False | | fill | —指定填充pack分配的空间
    —默认值是NONE,表示保持子组件的原始尺寸
    —还可以使用的值有:X(水平填充),Y(垂直填充)和BOTH(水平和垂直填充) | | in_ | —将该组件放到该选项指定的组件中
    —指定的组件必须是该组件的父组件 | | ipadx | —指定水平方向上的内边距 | | ipady | —指定垂直方向上的内边距 | | padx | —指定水平方向上的外边距 | | pady | —指定垂直方向上的外边距 | | side | —指定组件的放置位置
    —默认值是TOP
    —还可以设置的值有:LEFT,BOTTOM,RIGHT |

    pack_configure(**options) —跟 pack() 一样

    pack_forget() —将组件从屏幕中“删除” —并没有销毁该组件,只是看不到了 —可以通过 pack 或其他布局管理器显示已“删除”的组件

    pack_info() —以字典的形式返回当前的 pack 的选项

    pack_propagate(flag) —如果开启,父组件会自动调节尺寸以容纳所有子组件 —默认值是开启(flag=True)
    —该方法仅适用于父组件

    pack_slaves() —以列表形式返回该组件的所有子组件 —该方法仅适用于父组件

    grid 的方法:

    注:下边方法适用于所有组件

    grid(**options) —下面列举了各个选项的具体含义和用法

    | 选项 | 含义 | | —- | —- | | column | —指定组件插入的列(0表示第一列)
    —默认值是0 | | columnspan | —指定用多少列(跨列)显示该组件 | | in_ | —将该组件放到该选项指定的组件中
    —指定的组件必须是该组件的父组件 | | ipadx | —指定水平方向上的内边距 | | ipady | —指定垂直方向上的内边距 | | padx | —指定水平方向上的外边距 | | pady | —指定垂直方向上的外边距 | | row | —指定组件插入的行(0表示第一行) | | rowspan | —指定用多少行(跨行)显示该组件 | | sticky | —控制组件在grid分配的空间中的位置
    —可以使用N,E,S,W以及他们的组合来定位
    —使用加号(+)表示拉长填充,例如N+S表示将该组件垂直拉长填充网格,N+S+W+E表示填充整个网格
    —不指定该值则居中显示 |

    grid_bbox(column=None, row=None, col2=None, row2=None)

    —返回一个四元组描述该组件所在的限定矩形 —如果指定 column 和 row 参数,则返回该位置 (column, row) 的组件的限定矩形的描述

    grid_columnconfigure(index, **options)

    —设置列的属性—注意:设置的是该组件所拥有的grid序列

    可以设置的选项及含义如下:

    | 选项 | 含义 | | —- | —- | | minsize | —指定该列的最小宽度 | | pad | —指定该列中最大网格的水平边距 | | weight | —指定列与列之间的相对距离
    —默认值是0
    —说明:初创建窗口的时候,grid会自动根据组件的尺寸分配窗口的尺寸,当你拉伸窗口的尺寸就会有空白显示出来。这个选项正是指定列与列之间是否填充空白,默认是不填充的。另外,该选项的值是指定填充空白的倍数,例如weight=2的列会比weight=1的列填充多一倍的空白,所以需要平均填充的话,只需要所有的列都设置为weight=1即可。 |

    grid_configure(**options) —跟 grid() 一样

    grid_forget() —将组件从屏幕中“删除” —并没有销毁该组件,只是看不到了 —可以通过 grid
    或其他布局管理器显示已“删除”的组件,但该组件所在网格的选项设置不会恢复

    grid_info() —以字典的形式返回当前 grid 的选项

    grid_location(x, y) —返回位于(或接近)给定坐标(x, y)的网格位置 —返回值是一个 2 元组表示网格对应的(列, 行)

    grid_propagate(flag) —如果开启,父组件会自动调节尺寸以容纳所有子组件 —默认值是开启(flag=True)
    —该方法仅适用于父组件

    grid_remove() —跟 grid_forget() 一样,但恢复的时候会记住该组件所在网格的选项设置

    grid_rowconfigure(index, **options) —设置行的属性 —注意:设置的是该组件所拥有的grid的行

    可以设置的选项及含义如下:

    | 选项 | 含义 | | —- | —- | | minsize | —指定该列的最小宽度 | | pad | —指定该列中最大网格的垂直边距 | | weight | —指定行于行之间的相对距离
    —默认值是0 |

    grid_size() —返回该组件所拥有的 grid 的尺寸 —返回值是一个 2 元组,表示(列,行)分别的网格数

    grid_slaves(row=None, column=None) —以列表的形式返回该组件的所有子组件 —该方法仅适用于父组件

    place的方法

    注:下边的方法适用于所有的组件

    place(**options) —下方列举了各个选项的含义和用法

    | 选项 | 含义 | | —- | —- | | anchor | —控制组件在place分配的空间中的位置
    —N, NE, E, SE, S, SW, W, NW或CENTER来定位(EWSN表示东南西北)
    —默认值是NW | | bordermode | —指定边框模式(INSIDE或OUTSIDE)
    —默认值是INSIDE | | height | —指定该组件的高度(像素) | | in_ | —将该组件放到该选项指定的组件中
    —指定的组件必须是该组件的父组件 | | relheight | —指定该组件相对于父组件的高度
    —取值范围是0.0~1.0 | | relwidth | —指定该组件相对于父组件的宽度
    —取值范围是0.0~1.0 | | relx | —指定该组件相对于父组件的水平位置
    —取值范围是0.0~1.0 | | rely | —指定该组件相对于父组件的垂直位置
    —取值范围是0.0~1.0 | | width | —指定该组件的宽度(像素) | | x | —指定该组件的水平偏移位置(像素)
    —如果同时指定了relx选项,优先实现relx选项 | | y | —指定该组件的垂直偏移位置(像素)
    —如果同时指定了rely选项,优先实现rely选项 |

    place_configure(**options) —跟place()一样

    place_forget() —将组件从屏幕中“删除” —并没有销毁该组件,只是看不到了 —可以通过 place 或其他布局管理显示已“删除”的组件

    place_info() —以字典的形式返回当前 place 的选项

    place_slaves() —以列表的形式返回该组件的所有子组件 —该方法仅适用于父组件

    slaves() —跟 place_slaves() 一样