Tkinter 布局管理器(pack、grid、place)

该文章已生成可运行项目,

        Widget Layout Manager 组件布局管理器,顾名思义是用来对组件进行布局管理的。好比一位画家在画布上进行各种元素创作时进行布局一样。

        不禁好奇,为什么Tk不设计成每个组件自带布局管理功能。而要专门设计三个控件管理器?

        最大的可能是为了设计的灵活性.控件只需要关心其功能;布局逻辑集中在布局管理器中,便于调整。

初识布局管理器

        TK提供了三种布局管理器,pack、grid、place.

  • pack

        "打包"的意思.指定方向(上下或左右)对组件进行布局.

  • grid

        中文含义"网格"。名称体现了布局的方式:将父容器划分成 行(row)和列(column)组成的网格,然后根据网格坐标将控件放置在指定的位置上。

  • place

        "放置、定位"之意。通过明确指定控件的 位置(坐标)和 大小(宽度、高度),将控件精确地放置在父容器的指定位置上。

同一父容器中,只能使用一种布局管理器.

布局管理器常用方法

1、pack

选项参数作用取值
side控件间的排列方向

"top"(默认:由上往下排列、       

"bottom":由下往上排列、

"left":由左往右排列、

"right":由右往左排列

fill控件是否填充可用空间"none"(默认)、"x"、"y"、"both"
expand(填充)是否应该扩展以填充任何父容器中未被占用的空间。True 或 False(默认)
anchor(定位点) 控件在指定区域的对齐方式"center"(默认)
padx控件与周围控件或容器的水平间距整数(像素单位)
pady控件与周围控件或容器的垂直间距整数(像素单位)
ipadx控件内部内容(如按钮上文字、标签文本等)与控件水平侧的距离整数(像素单位)
ipady控件内部内容(如按钮上文字、标签文本等)与控件垂直侧的距离整数(像素单位)
总结 
  • 排列方向: 使用side影响控件间的排列方向;使用anchor影响控件在父容器中的位置。 

  • 填充空间:使用fill和expand 对父容器空白处进行填充
  • 间距: pad是padding(填充)缩写.i 是internal(内部的缩写).顾名思义:padx/pady 影响控件与周围控件的距离(填充);ipadx/ipady 影响控件内部内容与控件的距离(填充)。

 

2、grid

选项参数作用取值
row控件所在的行位置
column控件所在的列位置
sticky(粘附)控件在单元格内的对齐方式.

功能类似anchor,但是只可以设定N/S/W/E,即上/下/左/右对齐.

sticky=N+S
:可以拉长高度让控件在顶端和底端对齐。
sticky=W+E
:可以拉长宽度让控件在左边和右边对齐。
sticky=N+S+E
:可以拉长高度让控件在顶端和底端对齐,同时切齐右边。
sticky=N+S+W
:可以拉长高度让控件在顶端和底端对齐,同时切齐左边。
sticky=N+S+W+E
:可以拉长高度让控件在顶端和底端对齐,同时切齐左右边

rowspan控件跨越的行数整数,指定控件占用的行数。
columnspan控件跨越的列数整数,指定控件占用的列数。
padx控件与周围控件或容器的水平间距整数(像素单位)
pady控件与周围控件或容器的垂直间距整数(像素单位)
ipadx控件内部内容(如按钮上文字、标签文本等)与控件水平侧的距离整数(像素单位)
ipady控件内部内容(如按钮上文字、标签文本等)与控件垂直侧的距离整数(像素单位)
总结
  •  rowcolumn 来设置控件之间的位置。
  • sticky 用于定义控件在单元格内的对齐方式。作用类似于单元格内对空余父容器进行填补。
  • rowspancolumnspan 用来让控件跨越多个行或列
  • padxpadyipadxipady 用来控制控件的外边距内边距,即控件和周围空间的距离。

3、place 

选项参数作用取值
x控件相对于父容器的水平偏移量整数,表示控件的横坐标,单位为像素。
y控件相对于父容器的垂直偏移量整数,表示控件的纵坐标,单位为像素。
width控件的宽度整数,指定控件的宽度,单位为像素。
height控件的高度整数,指定控件的高度,单位为像素。
anchor控件在指定位置的对齐方式"n"、"s"、"e"、"w"、"ne"、"se" 等,用于指定控件如何对齐于 (x, y) 点。
relx控件的水平位置,相对于父容器的宽度的比例浮动值,范围 0 到 1,表示控件的水平位置占父容器宽度的比例。
rely控件的垂直位置,相对于父容器的高度的比例浮动值,范围 0 到 1,表示控件的垂直位置占父容器高度的比例。
relwidth控件的宽度,相对于父容器宽度的比例浮动值,范围 0 到 1,表示控件宽度占父容器宽度的比例。
relheight控件的高度,相对于父容器高度的比例浮动值,范围 0 到 1,表示控件高度占父容器高度的比例。
总结
  • place 布局管理器通过绝对位置x, y)或相对位置relx, rely)来放置控件。
  • anchor 用于设置控件相对于指定位置的对齐方式。
  • widthheight 设置控件的固定大小,relwidthrelheight 则是设置控件大小的相对比例。

place 布局管理器特别适合需要精确控制控件位置的场景。


 布局管理器代码实操

使用标签lable举例.

  • pack

from tkinter import *

# 创建窗口
root = Tk()

root.geometry("300x300+600+https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=200&pos_id=7jzYyvJO&pos_id=7jzYyvJO")

# 创建标签
lable1 = Label(root, text="红", bg="red")
lable2 = Label(root, text="黄", bg="yellow")
lable3 = Label(root, text="蓝", bg="blue")
lable4 = Label(root, text="绿", bg="green")


# ------ 布局 ----------------
# 默认布局:居中并从上往下排列
def pack_layout1():
    root.title("pack 例子1 默认布局")
    lable1.pack()
    lable2.pack()
    lable3.pack()
    lable4.pack()


# 指定side布局
def pack_layout2():
    root.title("pack 例子2 side")
    lable1.pack(side=TOP)
    lable2.pack(side=BOTTOM)
    lable3.pack(side=LEFT)
    lable4.pack(side=RIGHT)


# 指定fill布局,fill布局未起作用,因为top/bottom默认占据一行,left/right默认占据一列。
# 要想使其生效 需要使用expand(填充)
def pack_layout3():
    root.title("pack 例子3 fill")
    lable1.pack(side=TOP, fill=Y)
    lable2.pack(side=BOTTOM, fill=Y)
    lable3.pack(side=LEFT, fill=X)
    lable4.pack(side=RIGHT, fill=X)


# expand布局
def pack_layout4():
    root.title("pack 例子4 expand")
    lable1.pack(side=TOP, fill=Y, expand=True)
    lable2.pack(side=BOTTOM, fill=Y, expand=True)
    lable3.pack(side=LEFT, fill=X, expand=True)
    lable4.pack(side=RIGHT, fill=X, expand=True)


# anchor布局。
# 并不是在整个窗口进行布局.比如本例有4个标签组件,默认范围为4行(虽然pack中没有行的概念)。
# 而且控件没有出现在同一行
# 组件默认是按照**垂直方向(从上到下)**排列的,即side=TOP. anchor 只是控制组件在容器内的对齐位置
def pack_layout5():
    root.title("pack 例子5 anchor")
    lable1.pack(anchor=NW)
    lable2.pack(anchor=NE)
    lable3.pack(anchor=SW)
    lable4.pack(anchor=SE)


# 根据例子5,布局出现在同一行
def pack_layout6():
    root.title("pack 例子6 anchor")
    lable1.pack(side=LEFT, anchor=NW)
    lable2.pack(side=LEFT, anchor=NE)
    lable3.pack(side=LEFT, anchor=SW)
    lable4.pack(side=LEFT, anchor=SE)


# 间距布局
def pack_layout7():
    root.title("pack 例子6 间隔")
    lable1.pack(padx=20, pady=10, ipadx=10, ipady=5)
    lable2.pack(padx=20, pady=10, ipadx=10, ipady=5)
    lable3.pack(padx=20, pady=10, ipadx=10, ipady=5)
    lable4.pack(padx=20, pady=10, ipadx=10, ipady=5)


# 使用布局
pack_layout7()

root.mainloop()

结果:


  • grid

from tkinter import *

# 创建窗口
root = Tk()

root.geometry("300x300+600+https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=200&pos_id=7jzYyvJO&pos_id=7jzYyvJO")

# 创建标签
lable1 = Label(root, text="红AAA", bg="red")
lable2 = Label(root, text="黄AAAAA", bg="yellow")
lable3 = Label(root, text="蓝AAAAAAA", bg="blue")
lable4 = Label(root, text="绿AAAAAAAAA", bg="green")


# ------ grid布局 ----------------
# 默认布局
def grid_layout1():
    root.title("grid 例子1 默认布局")
    lable1.grid()
    lable2.grid()
    lable3.grid()
    lable4.grid()


# 指定行列.忽略某一行时,并不会空出来
def grid_layout2():
    root.title("grid 例子2 指定行列")
    lable1.grid(row=0, column=0)
    lable2.grid(row=2, column=0)
    lable3.grid(row=3, column=3)
    lable4.grid(row=4, column=3)


# sticky布局,补充对齐
def grid_layout3():
    root.title("grid 例子3 sticky")
    lable1.grid(row=0, column=0, sticky=EW)
    lable2.grid(row=2, column=0)
    lable3.grid(row=3, column=3, sticky=EW)
    lable4.grid(row=4, column=3)


# columnspan 布局
def grid_layout4():
    root.title("grid 例子4 columnspan")
    lable1.grid(row=0, column=0, sticky=EW)
    lable2.grid(row=0, column=1, sticky=EW)
    lable3.grid(row=1, column=0, columnspan=2, sticky=EW)
    lable4.grid(row=2, column=0, sticky=EW)



# 使用布局
grid_layout1()

root.mainloop()

结果:


  • place

from tkinter import *

# 创建窗口
root = Tk()

root.geometry("300x300+600+200")

# 创建标签
lable1 = Label(root, text="红AAA", bg="red")
lable2 = Label(root, text="黄AAAAA", bg="yellow")
lable3 = Label(root, text="蓝AAAAAAA", bg="blue")
lable4 = Label(root, text="绿AAAAAAAAA", bg="green")


# ------ place布局 ----------------
# x,y布局,指定左上角坐标
def place_layout1():
    root.title("place 例子1 ")
    lable1.place(x=1, y=1)
    lable2.place(x=100, y=200)
    lable3.place(x=150, y=150)
    lable4.place(x=200, y=100)


# 指定宽度、高度布局
def place_layout2():
    root.title("place 例子2 ")
    lable1.place(x=1, y=1)
    lable2.place(x=100, y=200, width=100, height=30)
    lable3.place(x=100, y=150, width=100, height=30)
    lable4.place(x=200, y=100, width=100, height=300)


# 相对位置布局
def place_layout3():
    root.title("place 例子3 ")
    lable1.place(relx=0.5, rely=0.5, relwidth=0.3, relheight=0.1)

# 使用布局
place_layout3()

root.mainloop()

place 布局太过于精确,还是pack与grid更加友好.


总结

布局管理器难度适用场景优点缺点
pack简单简单线性布局快速布局,代码简洁缺乏精确控制
grid中等表格布局或需对齐的界面精确位置,适合复杂布局代码较复杂,需提前规划
place较高自由、不规则或定制布局精确控制,灵活性高难以动态适配,开发较繁琐
本文章已经生成可运行项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值