python tkinter GUI开发之布局管理(pack,grid,place),详尽到附上每个参数的效果图

系列文章目录

python tkinter 桌面小程序开发从入门到界面美化(主题应用推荐)
Python 3.x cxfreeze打包exe教程(一路踩坑过来的)


文章目录

  • 系列文章目录
  • 一、Tkinter有三种布局管理方式
  • 二、使用步骤
    • 1. pack布局管理
      • 1.1 使用方法
      • 1.2 Pack可接收参数
        • 1.21 side: 停靠在哪个方向
        • 1.22 fill:填充
        • 1.23 expand:
        • 1.24 anchor: 锚选项
        • 1.25 ipadx、ipady: 组件内部间隙
        • 1.26 padx、pady: 组件外部间隙
        • 1.27 pack类提供下列函数
        • 1.28 例题提升
        • 1.29 Pack 布局总结
    • 2. Grid 布局管理
      • 2.1 使用方法
      • 2.2 Grid可接收参数
        • 2.21 sticky参数的使用
        • 2.22 columnspan
    • 3. Place 布局管理
      • 3.1 Place可接收参数
      • 3.2 使用案例
        • 3.21 使用绝对坐标将组件放到指定的位置
        • 3.22 使用相对坐标放置组件位置
        • 3.23 用place同时指定多个组件
        • 3.24 同时使用相对和绝对坐标
        • 3.25 使用in来指定放置的容器
        • 3.26 深入in用法
        • 3.27 事件与Place结合使用
  • 总结


一、Tkinter有三种布局管理方式

  • pack
  • grid
  • place

二、使用步骤

1. pack布局管理

pack 函数,默认先使用的放到上面,然 后依次向下排,它会给我们的组件一个自认为合适的位置和大小,这是默认方式。

通俗点来讲有点类似于PS图层,一层层堆叠打包起来

1.1 使用方法

from tkinter import *
root = Tk()

Button_1 = Button(root,text='Hello,World')
Button_1.pack()

root.mainloop()

1.2 Pack可接收参数

1.21 side: 停靠在哪个方向

设置组件的对齐方式LEFT RIGHT TOP BOTTOM

from tkinter import *
root = Tk()
root.geometry('800x300+300+150')			#创建一个800x300大小的GUI窗口

Button(root,text='LEFT').pack(side=LEFT)	#左
Button(root,text='TOP').pack(side=TOP)		#顶
Button(root,text='RIGHT').pack(side=RIGHT)	#右
Button(root,text='BOTTOM').pack(side=BOTTOM)#底

root.mainloop()

python tkinter GUI开发之布局管理(pack,grid,place),详尽到附上每个参数的效果图_第1张图片

1.22 fill:填充

设置组件是否向水平或垂直方向填充X Y BOTH NONE

from tkinter import *
root = Tk()
root.geometry('800x300+300+150')

Button(root,text='LEFT').pack(side=LEFT,fill=None)      #不填充(省略)
Button(root,text='TOP').pack(side=TOP,fill=X)           #水平方向填充
Button(root,text='RIGHT').pack(side=RIGHT,fill=Y)       #垂直方向填充
Button(root,text='BOTTOM').pack(side=BOTTOM,fill=BOTH)  #水平和垂直方向填充

root.mainloop()

python tkinter GUI开发之布局管理(pack,grid,place),详尽到附上每个参数的效果图_第2张图片

1.23 expand:

设置组件是否展开,当值为YES时,side选项无效。组件显示在父容器中心位置;若fill选项为BOTH,则填充父组件的剩余空间。默认为不展开YES 、NO(1、0)

  • True:随主窗体的大小变化
  • False:不随主窗体的大小变化
from tkinter import *
root = Tk()
root.geometry('800x300+300+150')

Button(root,text='LEFT').pack(expand=YES)      		 #随主窗体的大小变化
Button(root,text='TOP').pack(expand=YES)             #随主窗体的大小变化
Button(root,text='RIGHT').pack(expand=NO)            #不随主窗体的大小变化
Button(root,text='BOTTOM').pack(expand=NO)           #不随主窗体的大小变化

root.mainloop()

python tkinter GUI开发之布局管理(pack,grid,place),详尽到附上每个参数的效果图_第3张图片

1.24 anchor: 锚选项

锚选项,当可用空间大于所需求的尺寸时,决定组件被放置于容器的何处N、E、S、W、NW、NE、SW、SE、CENTER(默认值为CENTER) 表示八个方向以及中心

from tkinter import *
root = Tk()
root.geometry('800x300+300+150')

Button(root,text='NW').pack(anchor=NW)      #NW
Button(root,text='N').pack(anchor=N)        #N
Button(root,text='NE').pack(anchor=NE)      #NE
Button(root,text='W').pack(anchor=W)        #W
Button(root,text='C').pack(anchor=CENTER)   #CENTER
Button(root,text='E').pack(anchor=E)        #E
Button(root,text='NS').pack(anchor=SW)      #SW
Button(root,text='S').pack(anchor=S)        #S
Button(root,text='SE').pack(anchor=SE)      #SE


root.mainloop()

了解方向的应该知道指南针的N S W E
python tkinter GUI开发之布局管理(pack,grid,place),详尽到附上每个参数的效果图_第4张图片

1.25 ipadx、ipady: 组件内部间隙

设置x方向(或者y方向)内部间隙(子组件之间的间隔),可设置数值,默认是0,非负整数,单位为像素

from tkinter import *
root = Tk()
root.geometry('800x300+300+150')

Button(root,text='A').pack(ipadx=0)      #
Button(root,text='B').pack(ipadx=2)      #
Button(root,text='C').pack(ipadx=4)      #
Button(root,text='D').pack(ipadx=6)      #

Button(root,text='F').pack(ipady=0)      #
Button(root,text='G').pack(ipady=2)      #
Button(root,text='H').pack(ipady=4)      #
Button(root,text='I').pack(ipady=6)      #


root.mainloop()

python tkinter GUI开发之布局管理(pack,grid,place),详尽到附上每个参数的效果图_第5张图片

1.26 padx、pady: 组件外部间隙

设置x方向(或者y方向)外部间隙(与之并列的组件之间的间隔),可设置数值,默认是0,非负整数,单位为像素

理解组件外部间隙,一个很好的例子如下

from tkinter import *  
 
root = Tk()
root.geometry('800x300+300+150')

# padx 
Button(root, text='Left').pack(side=LEFT)
Button(root, text='Center').pack(side=LEFT)
Button(root, text='Right').pack(side=LEFT,padx=10)

# pady
Button(root,text='G').pack()      
Button(root,text='H').pack()      
Button(root,text='I').pack(pady=6)      

root.mainloop()

python tkinter GUI开发之布局管理(pack,grid,place),详尽到附上每个参数的效果图_第6张图片

1.27 pack类提供下列函数

使用组件实例对象调用:

函数名 描述
pack_slaves() 以列表方式返回本组件的所有子组件对象。
pack_configure(option=value) 给pack布局管理器设置属性,使用属性(option)= 取值(value)方式设置
propagate(boolean) 设置为True表示父组件的几何大小由子组件决定(默认值),反之则无关。
pack_info() 返回pack提供的选项所对应得值。
pack_forget() Unpack组件,将组件隐藏并且忽略原有设置,对象依旧存在,可以用pack(option, …),将其显示。
location(x, y) x, y为以像素为单位的点,函数返回此点是否在单元格中,在哪个单元格中。返回单元格行列坐标,(-1, -1)表示不在其中
size() 返回组件所包含的单元格,揭示组件大小。

1.28 例题提升

  1. 创建一个Frame容器fm1,将三个垂直排列的Button组件使用pack布局放入fm1容器中
  2. 然后创建fm2容器,同样将三个水平排列的Button组件放入
  3. 最后将两个Frame容器当做组件,使用pack布局放入根窗体容器中
  4. 分层布局,实现相对复杂一些的界面需求

答案引用CSDN一位博主的一篇例文,效果如下:

版权声明:本文为CSDN博主「编程之路从0到1」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/yingshukun/article/details/53983812

from tkinter import *    #注意模块导入方式,否则代码会有差别
 
class App:
    def __init__(self, master):
        #使用Frame增加一层容器
        fm1 = Frame(master)
        #Button是一种按钮组件,与Label类似,只是多出了响应点击的功能
        Button(fm1, text='Top').pack(side=TOP, anchor=W, fill=X, expand=YES)
        Button(fm1, text='Center').pack(side=TOP, anchor=W, fill=X, expand=YES)
        Button(fm1, text='Bottom').pack(side=TOP, anchor=W, fill=X, expand=YES)
        fm1.pack(side=LEFT, fill=BOTH, expand=YES)
 
        fm2 = Frame(master)
        Button(fm2, text='Left').pack(side=LEFT)
        Button(fm2, text='This is the Center button').pack(side=LEFT)
        Button(fm2, text='Right').pack(side=LEFT)        
        fm2.pack(side=LEFT, padx=10)
 
        
root = Tk()
root.title("Pack - Example")
display = App(root)
root.mainloop()

python tkinter GUI开发之布局管理(pack,grid,place),详尽到附上每个参数的效果图_第7张图片

1.29 Pack 布局总结

Pack 作为首选的布局管理方式,其运作方式并不是特别易于理解,已经由 Pack 布局完成的设计也很难做出改变。Grid 布局在1996年作为另一种可供选择的布局方式被引入,Grid 布局方式易学易用,但似乎大家还是习惯用 Pack。


2. Grid 布局管理

Python TkinterGrid布局管理器详解

官方生硬的文字就不写了,可以看作是网格布局,是最被推荐使用的布局。

GUI界面大多都是矩形的一个窗口,那么我们可以将其分为几行几列的网格,然后根据行列索引号来放置组件

用grid 布局时,需要指定两个参数,分别用row 表示行,column 表示列

注意:rowcolumn 的序号都从0开始
注意:不要试图在一个主窗口中混合使用pack和grid

2.1 使用方法

from tkinter import *

root=Tk()
root.title('Grid Example')
root.geometry('800x300+300+150')

#标签控件,显示文本和位图
Label(root,text="First").grid(row=0) #第1行
Label(root,text="Second").grid(row=1)#第2行

#输入控件
Entry(root).grid(row=0,column=1)    #第1行,第1列
Entry(root).grid(row=1,column=1)    #第2行,第1列

mainloop()

效果如下:
python tkinter GUI开发之布局管理(pack,grid,place),详尽到附上每个参数的效果图_第8张图片

2.2 Grid可接收参数

option 解释
column 插件布放的列数值,从0开始。默认值为0
columnspan 正常情况下,一个插件只占一个单元 。但是,你可以通过设置 columnspan 来合并一行中的多个邻近 单元 ,并用此 单元 放置本插件。比如, w.grid(row=0, column=2, columnspan=3),这会把插件 w 布置在 将第0行的2,3,4列合并后的 单元 中。
in_ in_=w2可以将 w 登记为 w2 的child插件。 w2 必须是 w 创建时指定parent插件的child插件。
ipadx x方向的内部填充。在插件内部,左右方向各填充指定长度的空间。
ipady y方向的内部填充。在插件内部,上下方向各填充指定长度的空间。
padx x方向的外部填充。在插件外部,左右方向各填充指定长度的空间。
pady y方向的内部填充。在插件内部,上下方向各填充指定长度的空间。
row 插件布放的行数值,从0开始。默认值 为 未布放行 的下一个数值。
rowspan 正常情况下,一个插件只占一个单元 。但是,你可以通过设置 rowspan 来合并一列中的多个邻近 单元 ,并用此 单元 放置本插件。比如, w.grid(row=3, column=2, rowspan=4, columnspan=3) ,这会把插件 w 布置在 合并了20个 单元 的区域中,也就是3-6行和2-6列。
sticky 这个参数用来确定:在插件正常尺寸下,如何分配 单元 中多余的空间。具体如下。
  • 如果没有声明sticky属性,默认将插件居中于 单元 中。
  • 通过设置 sticky=tk.NE (靠右上方),sticky=tk.SE(靠右下方),sticky=tk.SW(靠左下方),sticky=tk.NW(靠左上方),可以将插件布置在 单元 的某个角落。
  • 通过设置 sticky=tk.N(靠上方),sticky=tk.E(靠右方),sticky=tk.S(靠下方),sticky=tk.W(靠左方),可以将插件布置在 单元 的某个方向上。
  • 通过设置sticky=tk.N+tk.S,在垂直方向上延伸插件,并保持水平居中。
  • 通过设置sticky=tk.E+tk.W,在水平方向上延伸插件,并保持垂直居中。
  • 通过设置sticky=tk.N+tk.E+tk.W,在水平和垂直方向上延伸插件,填满 单元 。
  • 也可以使用其他的组合。比如,sticky=tk.N+tk.S+tk.W,在垂直方向上延伸插件,并靠左布放。

2.21 sticky参数的使用

from tkinter import *

root=Tk()
root.title('Grid Example')
root.geometry('800x300+300+150')

#标签控件,显示文本和位图
Label(root,text="First").grid(row=0,sticky=E) #第1行,靠右
Label(root,text="Second").grid(row=1,sticky=W)#第2行,靠左

#输入控件
Entry(root).grid(row=0,column=1)    #第1行,第1列
Entry(root).grid(row=1,column=1)    #第2行,第1列

mainloop()

python tkinter GUI开发之布局管理(pack,grid,place),详尽到附上每个参数的效果图_第9张图片

2.22 columnspan

from tkinter import *

root=Tk()
root.title('Grid Example')
root.geometry('800x300+300+150')

var=IntVar()

#标签控件,显示文本和位图
Label(root,text="First").grid(row=0,sticky=E) #第1行,靠右
Label(root,text="Second").grid(row=1,sticky=W)#第2行,靠左

#输入控件
Entry(root).grid(row=0,column=1)    #第1行,第1列
Entry(root).grid(row=1,column=1)    #第2行,第1列

#检查控件
button=Checkbutton(root,text="Precerve aspect",variable=var)
button.grid(sticky=W)

mainloop()

python tkinter GUI开发之布局管理(pack,grid,place),详尽到附上每个参数的效果图_第10张图片

from tkinter import *

root=Tk()
root.title('Grid Example')
root.geometry('800x300+300+150')

var=IntVar()

#标签控件,显示文本和位图
Label(root,text="First").grid(row=0,sticky=E) #第1行,靠右
Label(root,text="Second").grid(row=1,sticky=W)#第2行,靠左

#输入控件
Entry(root).grid(row=0,column=1)    #第1行,第1列
Entry(root).grid(row=1,column=1)    #第2行,第1列

#检查控件
button=Checkbutton(root,text="Precerve aspect",variable=var)
button.grid(columnspan=2,sticky=W)

mainloop()

python tkinter GUI开发之布局管理(pack,grid,place),详尽到附上每个参数的效果图_第11张图片

3. Place 布局管理

最简单最灵活的一种布局,使用组件坐标来放置组件的位置。但是不太推荐使用,在不同分辨率下,界面往往有较大差异

place 布局管理器可以通过坐标精确控制组件的位置

适用于一些布局更加灵活的场景

3.1 Place可接收参数

属性名 属性简析 取值 取值说明
anchor 锚选项,同pack布局 默认值为 NW 同pack布局
x、y 组件左上角的x、y坐标 整数,默认值0 绝对位置坐标,单位像素
relx、rely 组件相对于父容器的x、y坐标 0~1之间浮点数 相对位置,0.0表示左边缘(或上边缘),1.0表示右边缘(或下边缘)
width、height 组件的宽度、高度 非负整数 单位像素
relwidth、relheight 组件相对于父容器的宽度、高度 0~1之间浮点数 与relx(rely)取值相似

3.2 使用案例

案例参考https://blog.csdn.net/aa1049372051/article/details/51887144

3.21 使用绝对坐标将组件放到指定的位置

from tkinter import *
 
root = Tk()
root.title('使用绝对坐标将组件放到指定的位置')
root.geometry('800x300+300+150')

lb = Label(root, text='hello Place')
# lb.place(relx = 1,rely = 0.5,anchor = CENTER)
# 使用绝对坐标将Label放置到(0,0)位置上
lb.place(x=0, y=0, anchor=NW)
root.mainloop()
# x,y指定组件放置的绝对位置

python tkinter GUI开发之布局管理(pack,grid,place),详尽到附上每个参数的效果图_第12张图片

3.22 使用相对坐标放置组件位置

from tkinter import *
 
root = Tk()
root.title('使用相对坐标放置组件位置')
root.geometry('800x300+300+150')


lb = Label(root, text='hello Place')
# lb.place(relx = 1,rely = 0.5,anchor = CENTER)
# 使用相对坐标(0.5,0.5)将Label放置到(0.5*sx,0.5.sy)位置上
lb.place(relx=0.5, rely=0.5, anchor=CENTER)
root.mainloop()
# relx,rely指定组件放置的绝对位置,范围为(0-1.0)

python tkinter GUI开发之布局管理(pack,grid,place),详尽到附上每个参数的效果图_第13张图片

3.23 用place同时指定多个组件

from tkinter import *
 
root = Tk()
root.title('使用place同时指定多个组件')
root.geometry('800x300+300+150')


lb = Label(root, text='hello Place')
# lb.place(relx = 1,rely = 0.5,anchor = CENTER)
# 使用相对坐标(0.5,0.5)将Label放置到(0.5*sx,0.5.sy)位置上
v = IntVar()
for i in range(5):
    Radiobutton(
        root,
        text='Radio' + str(i),
        variable=v,
        value=i
    ).place(x=80 * i, anchor=NW)
root.mainloop()
# 使用place来指定各个Radiobutton的位置

python tkinter GUI开发之布局管理(pack,grid,place),详尽到附上每个参数的效果图_第14张图片

3.24 同时使用相对和绝对坐标

from tkinter import *
 
root = Tk()
root.title('同时使用相对和绝对坐标')
root.geometry('800x300+300+150')


lb1 = Label(root, text='hello Place', fg='green')
lb2 = Label(root, text='hello Place', fg='red')
# 先设置相对坐标为(0.5,0.5),再使用(-200,-200)将坐标作偏移(-200,-200)
lb1.place(relx=0.5, rely=0.5, anchor=CENTER, x=-200, y=-200)
# 先设置相对坐标为(0.5,0.5),再使用(-300,-300)将坐标作偏移(-300,-300)
lb2.place(relx=0.5, rely=0.5, anchor=CENTER, x=-300, y=-300)
root.mainloop()
# 同时使用相对和绝对坐标时,相对坐标优先操作,然后是在这个相对坐标的基础上进行偏移

python tkinter GUI开发之布局管理(pack,grid,place),详尽到附上每个参数的效果图_第15张图片

3.25 使用in来指定放置的容器

使用in属性来指定放置到的容器是那一个

from tkinter import *
 
root = Tk()
root.title('使用in来指定放置的容器')
root.geometry('800x300+300+150')


lb1 = Label(root, text='hello Place Label', fg='green')
bt1 = Button(root, text='hello Place Button', fg='red')
# 创建一个Label
lb1.place(relx=0.5, rely=0.5, anchor=CENTER)
 
# 在root同创建一个Button,目的是与bt1相比较
bt2 = Button(root, text='button in root', fg='yellow')
bt2.place(anchor=W)
# 在Label中创建一个Button
bt1.place(in_=lb1, anchor=W)
root.mainloop()
# 注意bt2放置的位置是在root的(0,0)处,而button1放置的位置是在lb1的(0,0)处,原因是由于bt1使用了in来指定放置的窗口为lb1

python tkinter GUI开发之布局管理(pack,grid,place),详尽到附上每个参数的效果图_第16张图片

3.26 深入in用法

使用in属性来指定放置到的容器是那一个,仅能是其master

from tkinter import *
 
root = Tk()
root.title('深入in用法')
root.geometry('800x300+300+150')


# 创建两个Frame用作容器
fm1 = Frame(root, bg='red', width=40, height=40)
fm2 = Frame(root, bg='blue', width=40, height=40)
# 再在fm1中创建一个fm3
fm3 = Frame(fm1, bg='yellow', width=20, height=20)
 
# 创建一个Label,它的master为fm1
lb1 = Label(fm1, text='hello Place', fg='green')
lb1.place(in_=fm1, relx=0.5, rely=0.5, anchor=CENTER)
# 创建一个Button,它的master为fm1
bt1 = Button(fm1, text='hello Place', fg='red')
 
# 将bt1放置到fm2中,程序报错
# 去掉下面这条语句就可以使用了,可以看到lb1已经正确的放置到fm1的中心位置了
# bt1.place(in_ = fm2,anchor = W)
 
# 将上面的语句改为下面,即将bt1放置到其fm1的子组件fm3中,这样也是可以的
bt1.place(in_=fm3, anchor=W)
 
fm1.pack()
fm2.pack()
fm3.pack()
root.mainloop()
# in不是可以随意指定放置的组件的,如果使用in这个参数这个组件必需满足:是其父容器或父容器的子组件

python tkinter GUI开发之布局管理(pack,grid,place),详尽到附上每个参数的效果图_第17张图片

3.27 事件与Place结合使用

最后使用两个place方法来动态改变两个Frame的大小

from tkinter import *
 
root = Tk()
root.title('事件与Place结合使用')
root.geometry('800x300+300+150')


split = 0.5
fm1 = Frame(root,bg = 'red')
fm2 = Frame(root,bg = 'blue')
# 单击fm1时增大它的占有区域0.1
def incFm1(event):
    global split
    if split < 1:
        split += 0.1
    fm1.place(rely = 0,relheight = split,relwidth = 1)
    fm2.place(rely = split,relheight = 1 - split,relwidth = 1)
# 单击fm2时增大它的占有区域0.1
def incFm2(event):
    global split
    if split > 0:
        split -= 0.1
    fm1.place(rely = 0,relheight = split,relwidth = 1)
    fm2.place(rely = split,relheight = 1 - split,relwidth = 1)
 
# 这两语句要使用,不然开始看不到两个frame,也就没法点击它们了
fm1.place(rely = 0,relheight = split,relwidth = 1)
fm2.place(rely = split,relheight = 1 - split,relwidth = 1)
# 绑定单击事件
fm1.bind('',incFm1)
fm2.bind('',incFm2)
 
root.mainloop()
# 为SplitWindow的原型了,再改动一下就可以实现一个SplitWindow了。

python tkinter GUI开发之布局管理(pack,grid,place),详尽到附上每个参数的效果图_第18张图片
python tkinter GUI开发之布局管理(pack,grid,place),详尽到附上每个参数的效果图_第19张图片


总结

以上就是布局管理的总结和学习,文中有些内容摘自平台已注明出处,图片均为原创,排版纯按照个人喜好来排布,鄙人稍微有些强迫症,一个好的排版可以更快的吸收,如果有任何问题请下方留言,好看收藏+关系,谢谢

你可能感兴趣的:(python,tkinter,grid,place,pack)