窗口控件配置
一个窗口含有多个Widget控件,这时就会牵涉应如何将这些Widget控件配置到容器或窗口内
Widget Layout Manager
在设计GUI程序时,可以使用三种方法包装和定位各组件在容器或窗口内的位置
这三个方法又称窗口控件配置管理员(Widget Layout Manager)
- pack方法
- grid方法
- place方法
pack方法
pack方法,其实在tkinter内是一个类别
这是最常使用的控件配置管理方法,它是使用相对位置的概念处理Widget控件配置,至于控件的正确位置则是由pack方法自动完成。
pack方法的语法格式如下:
pack(options,...)
options参数可以是side、fill、padx/pady、ipadx/ipady、anchor。
side参数
side参数可以垂直或水平配置控件
例子: 三个标签
from tkinter import * window = Tk() window.title("demo") lab1 = Label(window,text="wkk",bg="lightyellow") # 背景 浅黄色 lab2 = Label(window,text="hahaha",bg="lightgreen") lab3 = Label(window,text="lalala",bg="lightblue") lab1.pack() # 包装 与 定位组件 lab2.pack() lab3.pack() window.mainloop()
当窗口中有多个组件时,使用pack可以让组件由上往下排列显示, 这是系统的默认设置
使用pack方法时,也可以增加side参数设置组件的排列方式,此参数的取值如下:
- TOP:这是默认值,由上往下排列
- BOTTOM:由下往上排列。
- LEFT:由左往右排列。
- RIGHT:由右往左排列。
**例子:**在pack方法内增加“side=LEFT”, 同时将标签的宽度改为15
from tkinter import * window = Tk() window.title("demo") lab1 = Label(window,text="wkk",bg="lightyellow", width = 15) lab2 = Label(window,text="hahaha",bg="lightgreen", width = 15) lab3 = Label(window,text="lalala",bg="lightblue", width = 15) lab1.pack(side = LEFT) lab2.pack(side = LEFT) lab3.pack(side = LEFT) window.mainloop()
例子: 混合使用side参数
from tkinter import * window = Tk() window.title("demo") lab1 = Label(window,text="wkk",bg="lightyellow", width = 15) lab2 = Label(window,text="hahaha",bg="lightgreen", width = 15) lab3 = Label(window,text="lalala",bg="lightblue", width = 15) lab1.pack() lab2.pack(side = RIGHT) lab3.pack(side = LEFT) window.mainloop()
**例子:**列出relief的所有属性
from tkinter import * Reliefs = ["flat","groove","raised","ridge","solid","sunken"] root = Tk() root.title("demo") for Relief in Reliefs: Label(root,text = Relief,relief = Relief,fg = "lightblue",font = "Times 20 bold").pack(side=LEFT,padx=5) root.mainloop()
例子: 列出所有的bitmaps位图
from tkinter import * bitMaps = ["error","hourglass","info","questhead","question","warning","gray12","gray25","gray50","gray75"] root = Tk() root.title("demo") for bitMap in bitMaps: Label(root,bitmap = bitMap).pack(side=LEFT,padx=5) root.mainloop()
padx/pady 参数
使用pack方法时,可以使用padx/pady参数设定控件边界与容器(可想成窗口边界)的距离或是控件边界间的距离。
在默认环境下窗口控件间的距离是1像素,如果希望有适度间距,可以设置参数padx/pady,代表水平间距/垂直间距,可以分别在组件间增加间距。
from tkinter import * window = Tk() window.title("demo") lab1 = Label(window,text="wkk",bg="lightyellow", width = 15) lab2 = Label(window,text="hahaha",bg="lightgreen", width = 15) lab3 = Label(window,text="lalala",bg="lightblue", width = 15) lab1.pack(fill=X) # 填满X轴包装与定位组件 lab2.pack(pady=10) # y轴增加10 pix lab3.pack(fill=X) # 填满X轴包装与定位组件 window.mainloop()
边界是会叠加的
在“wkk学”标签pack内增加pady=10, ,此时“wkk”标签边界与上边容器边界间距是10,但是它与“hahaha”标签间的间距由于彼此影响所以将是20。
ipadx / ipady参数
- ipadx参数可以控制标签文字与标签容器的x轴间距
- ipady参数可以控制标签文字与标签容器的y轴间距
from tkinter import * window = Tk() window.title("demo") lab1 = Label(window,text="wkk",bg="lightyellow", width = 15) lab2 = Label(window,text="hahaha",bg="lightgreen", width = 15) lab3 = Label(window,text="lalala",bg="lightblue", width = 15) lab1.pack() # 填满X轴包装与定位组件 lab2.pack(ipady = 30) # ipady = 30 lab3.pack() # 填满X轴包装与定位组件 window.mainloop()
anchor参数
这个参数可以设定Widget控件在窗口中的位置,但是这里是设定控件内容在控件区域的位置设置(标签文字在标签区域的位置)
from tkinter import * window = Tk() window.title("demo") window.geometry("300x180") okLabel = Label(window,text="OK",font="Times 20 bold",fg="white",bg = "blue") okLabel.pack(anchor=S,side=RIGHT,padx=10,pady=10) # 从右开始,在S方向设置 window.mainloop()
fill参数
fill参数的主要功能是告诉pack管理程序,设置控件填满所分配容器区间的方式
- 如果是fill=X表示控件可以填满所分配空间的X轴不留白
- 如果是fill=Y表示控件可以填满所分配空间的Y轴不留白
- 如果是fill=BOTH表示控件可以填满所分配空间的X轴和Y轴
- fill默认值是NONE,表示保持原大小
from tkinter import * window = Tk() window.title("demo") lab1 = Label(window,text="wkk",bg="lightyellow") # 背景 浅黄色 lab2 = Label(window,text="hahaha",bg="lightgreen") lab3 = Label(window,text="lalala",bg="lightblue") lab1.pack(fill = X) # 包装 与 定位组件 填满X lab2.pack() lab3.pack(fill = X) window.mainloop()
如果所分配容器区间已经满了,则使用此fill参数将不会有任何作用。
expand参数
expand参数可设定Widget控件是否填满额外的父容器空间
- 默认是False(或是0),表示不填满
- 如果是True(或是1)表示填满
**例1: **从上到下配置标签
from tkinter import * window = Tk() window.title("demo") lab1 = Label(window,text="wkk",bg="lightyellow") # 背景 浅黄色 lab2 = Label(window,text="hahaha",bg="lightgreen") lab3 = Label(window,text="lalala",bg="lightblue") lab1.pack(fill = X) # 包装 与 定位组件 填满X lab2.pack(fill=BOTH,expand=True) lab3.pack(fill = X) window.mainloop()
例2: 从左到右配置标签
from tkinter import * window = Tk() window.title("demo") lab1 = Label(window,text="wkk",bg="lightyellow") # 背景 浅黄色 lab2 = Label(window,text="hahaha",bg="lightgreen") lab3 = Label(window,text="lalala",bg="lightblue") lab1.pack(fill = X,side=LEFT) # 包装 与 定位组件 填满X lab2.pack(fill=BOTH,expand=True,side=LEFT) lab3.pack(fill = X,side=LEFT) window.mainloop()
pack的方法
pack其实在Python tkinter中是一个类别,它提供下列方法
**例子:**列出执行前后Widget控件中的内容
from tkinter import * window = Tk() window.title("demo") print("执行前") print(window.slaves()) lab1 = Label(window,text="wkk",bg="lightyellow") # 背景 浅黄色 lab2 = Label(window,text="hahaha",bg="lightgreen") lab3 = Label(window,text="lalala",bg="lightblue") lab1.pack(fill = X) # 包装 与 定位组件 填满X lab2.pack(fill=BOTH) lab3.pack(fill = X) print("执行后") print(window.pack_slaves()) window.mainloop()
slaves() 也可以写为 : pack_slaves()
grid方法
以格状或者类似Excel电子表格方式包装和定位窗口组件的方法。
grid方法的语法格式如下:
grid(options,...)
options参数可以是row、column、padx/pady、rowspan、columnspan、sticky。
row 和 column
row和column参数的概念
可以适度调整grid( )方法内的row和column值,即可包装窗口组件的位置。
from tkinter import * window = Tk() window.title("demo") lab1 = Label(window,text="wkk",bg="lightyellow") # 背景 浅黄色 lab2 = Label(window,text="hahaha",bg="lightgreen") lab3 = Label(window,text="lalala",bg="lightblue") lab1.grid(row=0,column=0) #格状包装 lab2.grid(row=1,column=0) lab3.grid(row=2,column=0) window.mainloop()
columnspan参数
可以设定控件在column方向的合并数量
**例子:**使用grid方法建立含8个标签的应用
from tkinter import * window = Tk() window.title("demo") lab1 = Label(window,text="标签1",relief="raised") # 背景 浅黄色 lab2 = Label(window,text="标签2",relief="raised") lab3 = Label(window,text="标签3",relief="raised") lab4 = Label(window,text="标签4",relief="raised") lab5 = Label(window,text="标签5",relief="raised") lab6 = Label(window,text="标签6",relief="raised") lab7 = Label(window,text="标签7",relief="raised") lab8 = Label(window,text="标签8",relief="raised") lab1.grid(row=0,column=0) lab2.grid(row=0,column=1,columnspan=2) #lab3.grid(row=1,column=0) lab4.grid(row=1,column=1) lab5.grid(row=2,column=0) lab6.grid(row=2,column=1) lab7.grid(row=3,column=0) lab8.grid(row=3,column=1) window.mainloop()
如果发生了标签1和标签2的区间是被一个标签占用的情况,此时就是使用columnspan参数的场合。
**例子:**将标签1和标签2合并成一个标签
from tkinter import * window = Tk() window.title("demo") lab1 = Label(window,text="标签1",relief="raised") # 背景 浅黄色 lab2 = Label(window,text="标签2",relief="raised") lab3 = Label(window,text="标签3",relief="raised") lab4 = Label(window,text="标签4",relief="raised") lab5 = Label(window,text="标签5",relief="raised") lab6 = Label(window,text="标签6",relief="raised") lab7 = Label(window,text="标签7",relief="raised") lab8 = Label(window,text="标签8",relief="raised") lab1.grid(row=0,column=0,columnspan=2) #lab2.grid(row=0,column=1) lab3.grid(row=1,column=0) lab4.grid(row=1,column=1) lab5.grid(row=2,column=0) lab6.grid(row=2,column=1) lab7.grid(row=3,column=0) lab8.grid(row=3,column=1) window.mainloop()
rowspan参数
可以设定控件在row方向的合并数量
**例子:**标签1和标签3合并成一个标签
from tkinter import * window = Tk() window.title("demo") lab1 = Label(window,text="标签1",relief="raised") # 背景 浅黄色 lab2 = Label(window,text="标签2",relief="raised") lab3 = Label(window,text="标签3",relief="raised") lab4 = Label(window,text="标签4",relief="raised") lab5 = Label(window,text="标签5",relief="raised") lab6 = Label(window,text="标签6",relief="raised") lab7 = Label(window,text="标签7",relief="raised") lab8 = Label(window,text="标签8",relief="raised") lab1.grid(row=0,column=0,rowspan=2) lab2.grid(row=0,column=1) #lab3.grid(row=1,column=0) lab4.grid(row=1,column=1) lab5.grid(row=2,column=0) lab6.grid(row=2,column=1) lab7.grid(row=3,column=0) lab8.grid(row=3,column=1) window.mainloop()
padx 和 pady 参数
与pack方法的padx/pady参数相同,增加标签间的间距
from tkinter import * window = Tk() window.title("demo") lab1 = Label(window,text="标签1",relief="raised") # 背景 浅黄色 lab2 = Label(window,text="标签2",relief="raised") lab3 = Label(window,text="标签3",relief="raised") lab4 = Label(window,text="标签4",relief="raised") lab5 = Label(window,text="标签5",relief="raised") lab6 = Label(window,text="标签6",relief="raised") lab7 = Label(window,text="标签7",relief="raised") lab8 = Label(window,text="标签8",relief="raised") lab1.grid(row=0,column=0,padx=5,pady=5) lab2.grid(row=0,column=1,padx=5,pady=5) lab3.grid(row=1,column=0,padx=5,pady=5) lab4.grid(row=1,column=1,padx=5,pady=5) lab5.grid(row=2,column=0,padx=5,pady=5) lab6.grid(row=2,column=1,padx=5,pady=5) lab7.grid(row=3,column=0,padx=5,pady=5) lab8.grid(row=3,column=1,padx=5,pady=5) window.mainloop()
sticky参数
功能类似anchor,但是只可以设定N/S/W/E,即上/下/左/右对齐。
默认情况,原则上相同column的Widget控件,如果宽度不同时,grid方法会保留最宽的控件当作基准,这时比较短的控件会居中对齐。
from tkinter import * window = Tk() window.title("demo") lab1 = Label(window,text="wkk",bg="lightyellow") # 背景 浅黄色 lab2 = Label(window,text="hahaha",bg="lightgreen") lab3 = Label(window,text="lalala",bg="lightblue") lab1.grid(row=0,column=0,sticky=W) lab2.grid(row=1,column=0) lab3.grid(row=2,column=0,sticky=W) window.mainloop()
sticky参数的可能值N/S/W/E也可以组合使用:
- sticky=N+S:可以拉长高度让控件在顶端和底端对齐
- sticky=W+E:可以拉长宽度让控件在左边和右边对齐
- sticky=N+S+E:可以拉长高度让控件在顶端和底端对齐,同时切齐右边
- sticky=N+S+W:可以拉长高度让控件在顶端和底端对齐,同时切齐左边
- sticky=N+S+W+E:可以拉长高度让控件在顶端和底端对齐,同时切齐左右边
from tkinter import * window = Tk() window.title("demo") lab1 = Label(window,text="wkk",bg="lightyellow") # 背景 浅黄色 lab2 = Label(window,text="hahaha",bg="lightgreen") lab3 = Label(window,text="lalala",bg="lightblue") lab1.grid(row=0,column=0,sticky=W+E) # 左右边对齐 lab2.grid(row=1,column=0) lab3.grid(row=2,column=0,sticky=W+E) window.mainloop()
grid方法的应用
使用grid方法建立色彩标签
from tkinter import * root = Tk() root.title("demo") Colors = ["red","orange","yellow","green","blue","purple"] r= 0 for color in Colors: Label(root,text=color,relief="groove",width=20).grid(row=r,column=0) Label(root,bg=color,relief="ridge",width= 20).grid(row=r,column=1) r+=1 root.mainloop()
rowconfigure() 和 columnconfigure()
在设计Widget控件的布局时,有时候会碰上窗口缩放大小,此时可以使用这两个方法设定第几个row或column的缩放比例。
rowconfigure(0,weight=1) #row 0 的控件窗口改变大小时 缩放比例为 1 columnconfigure(0,weight=1) #column 0 的控件窗口改变大小时 缩放比例为 1
**例子:**认识rowconfigure( )、columnfigure( )的用法
from tkinter import * root = Tk() root.title("demo") root.rowconfigure(1,weight=1) root.columnconfigure(0,weight=1) lab1 = Label(root,text="Label 1",bg="pink") lab2 = Label(root,text="Label 2",bg="lightblue") lab3 = Label(root,text="Label 3",bg="yellow") lab1.grid(row=0,column=0,padx=5,pady=5,sticky=W+E) lab2.grid(row=0,column=1,padx=5,pady=5) lab3.grid(row=1,column=0,columnspan=2,padx=5,pady=5,sticky=N+S+W+E) root.mainloop()
place方法
使用直接指定方式将Widget控件放在容器(可想成窗口)中的方法
语法格式如下:
place(options,...)
options参数可以是height/width、relx/rely、x/y、relheight/relwidth、bordermode、anchor。
x / y参数
place( )方法内的x和y参数可直接设定窗口组件的左上方位置,单位是像素。
窗口显示区的左上角是(x=0,y=0),x是向右递增,y是向下递增。
同时,使用这种方法时,窗口将不会自动重设大小而是使用默认的大小显示
例子: 使用place( )方法直接设定标签的位置
from tkinter import * window = Tk() window.title("demo") lab1 = Label(window,text="wkk",bg="lightyellow") # 背景 浅黄色 lab2 = Label(window,text="hahaha",bg="lightgreen") lab3 = Label(window,text="lalala",bg="lightblue") lab1.place(x=0,y=0) # 直接定位 lab2.place(x=30,y=50) lab3.place(x=60,y=100) window.mainloop()
width / height 参数
有时候在设计窗口应用程序时,所预留的空间有限,如果想要将图片插入窗口内,却担心图片太大,可以在插入图片时同时设定图片的大小,此时可以使用width/height参数,这两个参数可以直接设定Widget控件的实体大小。
from tkinter import * window = Tk() window.title("demo") window.geometry("640x480") hand = PhotoImage(file="./img/hand1.png") lab1 = Label(window,image=hand) lab1.place(x=20,y=30,width=200,height=120) window.mainloop()
relx / rely 参数 与 relwidth /relheight 参数
relx/rely可以设置相对于父容器(可想成父窗口)的位置 ,relwidth/relheight设置相对大小。
这个相对位置与相对大小是相对于父窗口而言,其值为0.0 ~ 1.0。
from tkinter import * window = Tk() window.title("demo") window.geometry("640x480") hand = PhotoImage(file="./img/hand1.png") lab1 = Label(window,image=hand) lab1.place(relx=0.1,rely=0.1,relwidth=0.8,relheight=0.8) # 相对值 window.mainloop()
在设计时,如果参数的某个相对大小未设定(可能是relwidth或relheight),未设置的部分将以实际大小显示,此时可能需要放大窗口宽度才可以显示。
Widget控件位置总结
使用tkinter模块设计GUI程序时,虽然可以使用place( )方法很精确地设置控件的位置,不过建议尽量使用pack( )和grid( )方法定位组件,,因为当窗口中组件较多时,使用place( )计算组件位置较不方便,同时若有新增或减少组件时又须重新计算设置组件位置,这样会比较不方便。