Tkinter参考中最推荐使用的一个布局器。实现机制是将Widget逻辑上分割成表格,在指定的位置放置想要的Widget就可以了。
使用grid显示窗体的主要流程:
self.thing = constructor(parent,……)#constructor可以为Button,Frame等
self.thing.grid(……)
grid方法介绍:
w.grid(option=value,……)
向窗体注册并显示控件
主要参数:
column: 控件放置位置的列数,从0开始算起,默认为0;
clomnspan: 设置单元格横向跨越的列数,例如:w.grid(row=0, column = 2, columnspan=3);
in_:重新设置w为窗体w2的子窗体,方法:in_=w2.w2必须是w的父窗体子类;
ipadx:设置控件里面x方向空白区域大小;
ipady:设置控件里面y方向空白区域大小;
padx:设置控件周围x方向空白区域保留大小;
pady:设置控件周围y方向空白区域保留大小;
row:控制放置的行数,从0开始算起,默认为上一个位占领的行数
rowspan:设置单元格纵向跨越的列数,例如:w.grid(row=0, column = 2,rowspan=4, columnspan=5);
sticky:设置对齐方式
如果未设置对齐方式,默认为将控件放置在窗体中间。对齐方式主要有如下几种:
1) 通过使用sticky=NE(右上角),SE(右下角),SW(左下角),NW(左上角)来设置控件位置
2) 通过使用sticky=N(上中),E(右中),S(底中),W(左中)来设置控件放置中间位置
3) sticky=N+S,向垂直方向拉升而保持水平中间对齐
4) sticky=E+W,向水平方向拉升而保持垂直中间对齐
5) sticky=N+E+S+W,以水平方向和垂直方向拉升的方式填充单元格
这部分内容一直没弄懂,界面的布局要靠不停的尝试,略有点拙急。原因就在于pack(), grid(), place(),三个方法一个都没用好,widget中与尺寸有关的height和width选项的度量单位没弄明白。希望今天能一劳永逸的解决这个问题~~~
***************************************************************************************************
Widget尺寸:
要确定几何布局,首先需要弄清楚widget的尺寸,widget的尺寸信息由option中的height和width来确定。不同类型的widget,height和width的依据标准还不同(这就是为啥弄不清楚的原因),首先说明两种标准:
- Dimensions:如果设定为int,那么表示的是像素值,也可以使用单位c=Centimeters, i=Inches, m=Millimeters, p=Printer’s points(about 1/72”);
- Characters:许多与character相关的widget 是以Font size来度量自身尺寸的。Font可以使用tkFont.Font(size)来创建,size表示的是字符的高度,int表示point,-int表 示的像素值,例如-20表示20个像素大小,20则表示20-point,这里指的是单个character的大小,反应在widget中指的是以单个 character大小为单位;
下面将widget一句的标准列举出来:
Widget | Height | Width |
Button | text行数 | Characters标准 |
Canvas | Dimensions标准 | Dimensions标准 |
CheckButton | text行数 | Characters标准 |
Entry | 单行 | Characters标准 |
Frame | Dimensions标准 | Dimensions标准 |
LabelFrame | Dimensisons标准 | Dimensions标准 |
Label | text行数 | Characters标准 |
ListBox | text行数 | Characters标准 |
Menu | 无 | 无 |
MenuButton | text行数 | Characters标准 |
Message | 无 | Dimensions标准 |
OptionMenu | Dimensions标准 | Dimensions标准 |
PanedWindow | 子widget | 子widget |
Radiobutton | text行 | Characters标准 |
Scale | 无 | Dimensions标准 |
Scrollbar | 无 | Dimensions标准 |
Spinbox | 无 | Characters标准 |
Text | text行 | Characters标准 |
text的高度也不是完全的按照height*fontSize来的,略囧
****************************************************************************************************
Pack
采用块的方式组织配件,它是一个弹性的容器,widget的大小会随着内部child widget的大小而变化,但是可以使用.propagate(False),限定widget的大小不变。如果不指定pack的option参数,pack会从上到下的放置widget
==================================================================================
首先是option选项:
1.expand:当值为yes,side选项无效。组件显示在父组件的中心位置;若fill=both,则填充父组件的剩余空间
9 from Tkinter import *
10
11 root = Tk()
12 #默认的是从上至下的放置
13 win_1 = Frame(root, width=200, height=100, bg=’red’)
14 win_1.propagate(False)
15 win_1.pack()
16 button_1 = Button(win_1, text=’button_1′)
17 button_1.pack()
18
19 #expand=YES,是放置在正中心
20 win_2 = Frame(root, width=200, height=100, bg=’yellow’)
21 win_2.propagate(False)
22 win_2.pack()
23 button_2 = Button(win_2, text=’button_2′)
24 button_2.pack(expand=YES)
25
26 #expand=YES,fill=BOTH是填充父组件剩余的位置
27 win_3 = Frame(root, width=200, height=100, bg=’green’)
28 win_3.propagate(False)
29 win_3.pack()
30 button_3 = Button(win_3, text=’button_3′)
31 button_3.pack(expand=YES, fill=BOTH)
结果如下:
====================================================================================
2.fill:填充空间。当side=top或bottom时,填充x方向;当side=left或right时,填充y反向;当expend=yes时,fill=both,填充父组件的剩余空间;
33 #fill=X, 填充x方向
34 win_4 = Frame(root, width=200, height=100, bg=’green’)
35 win_4.propagate(False)
36 win_4.pack()
37 button_4 = Button(win_4, text=’button_4′)
38 button_4.pack(fill=X)
39
40 #expand=YES, fill=X, 位于中间,填充x方向
41 win_5 = Frame(root, width=200, height=100, bg=’blue’)
42 win_5.propagate(False)
43 win_5.pack()
44 button_5 = Button(win_5, text=’button_5′)
45 button_5.pack(expand=YES, fill=X)
46
47 #expand=YES, fill=Y, 填充Y方向
48 win_6 = Frame(root, width=200, height=100, bg=’green’)
49 win_6.propagate(False)
50 win_6.pack()
51 button_6 = Button(win_6, text=’button_6′)
52 button_6.pack(expand=YES, fill=Y)
结果如下:
================================================================================
3.ipadx(ipady):组件内部在x(y)方向上填充的空间大小,默认单位是像素
55 win = Frame(root, width=200, height=100, bg=’yellow’)
56 win.propagate(False)
57 win.pack()
58 button = Button(win, text=’button’)
59 button.pack(expand=YES)
60
61 win_7 = Frame(root, width=200, height=100, bg=’red’)
62 win_7.propagate(False)
63 win_7.pack()
64 button_7 = Button(win_7, text=’button_7′)
65 button_7.pack(expand=YES, ipadx=10)
66
67 win_8 = Frame(root, width=200, height=100, bg=’green’)
68 win_8.propagate(False)
69 win_8.pack()
70 button_8 = Button(win_8, text=’button_8′)
71 button_8.pack(expand=YES, ipady=10)
结果如下:
==================================================================================
4.padx(pady):组件外部在x(y)方向上填充的空间大小,默认单位是像素
32 #expand=YES, pad
33 win_10 = Frame(root, width=200, height=100, bg=’yellow’)
34 win_10.propagate(False)
35 win_10.pack()
36 button_10 = Button(win_10, text=’button_10′)
37 button_10.pack()
38
39 button_11 = Button(win_10, text=’button_11′)
40 button_11.pack(padx=10)
41
42 button_12 = Button(win_10, text=’button_12′)
43 button_12.pack(pady=10)
结果如下:
=======================================================================
5.side:定义停靠在父组件的哪一边;
6.before:将本组件于所选组建对象之前pack,类似于先创建本组件再创建选定组件
7.after:将本组件于所选组建对象之后pack,类似于先创建选定组件再创建本组件
8.in_:将本组件作为所选组建对象的子组件,类似于指定本组件的master为选定组件
9.anchor:对齐方式,左对齐=w,右对齐=e,顶对齐=n,底对齐=s,可以各种组合’wens’为填充全部,这里的参照对象是父组件
32 #expand=YES, pad
33 win_10 = Frame(root, width=200, height=150, bg=’yellow’)
34 win_10.propagate(False)
35 win_10.pack()
36 button_10 = Button(win_10, text=’button_10′)
37 button_10.pack(anchor=’e’)
38
39 button_11 = Button(win_10, text=’button_11′)
40 button_11.pack(anchor=’w’)
41
42 button_12 = Button(win_10, text=’button_12′)
43 button_12.pack(anchor=’n’)
44
45 button_13 = Button(win_10, text=’button_13′)
46 button_13.pack(anchor=’se’)
结果如下:
==================================================================================
****************************************************************************************************
Grid
grid采用行列确定位置,行列交汇处为一个单元格。每一列中,列宽由这一列中最宽的单元格确定。每一行 中,行高由这一行中最高的单元格决定。组件并不是充满整个单元格的,你可以指定单元格中剩余空间的使用。你可以空出这些空间,也可以在水平或竖直或两个方 向上填满这些空间。你可以连接若干个单元格为一个更大空间, 这一操作被称作跨越。创建的单元格必须相临。
Grid方法有点难理解,行列号只是指定放置的相对位置,而不是实际的像素坐标。
=========================================================================================
option常用的选项如下:
1.column:组件所置单元格的列号;
2.row:组件所置单元格的行号;
9 from Tkinter import *
10
11 root = Tk()
12
13 win = Frame(root, height=400, width=400)
14 win.grid_propagate(False)
15 win.grid()
16
17 button_1 = Button(win, text=’button_1′, height=2, width=10)
18 button_1.grid(row=0, column=0)
19
20 button_2 = Button(win, text=’button_2′)
21 button_2.grid(row=1, column=0)
22
23 button_3 = Button(win, text=’button_3′, height=2)
24 button_3.grid(row=0, column=1)
25
26 button_4 = Button(win, text=’button_4′, height=1)
27 button_4.grid(row=2, column=0)
28
29 button_5 = Button(win, text=’button_5′, height=1)
30 button_5.grid(row=3, column=1)
31
32 root.mainloop()
结果如下:
3.columnspan:从组件所置单元格算起在列方向上的跨度;
4.rowspan:从组件所置单元格算起在行方向上的跨度
9 from Tkinter import *
10
11 root = Tk()
12
13 win = Frame(root, height=400, width=400)
14 win.grid_propagate(False)
15 win.grid()
16
17 button_1 = Button(win, text=’button_1′)
18 button_1.grid(row=0, column=0, rowspan=2, columnspan=2)
19
20 button_2 = Button(win, text=’button_2′)
21 button_2.grid(row=0, column=1)
22
23 button_3 = Button(win, text=’button_3′)
24 button_3.grid(row=1, column=0)
25
26 root.mainloop()
结果如下(比较难理解):
=================================================================================
5.ipadx(ipady):组件内部在x(y)方向上填充的空间大小,默认单位为像素;
6.padx(pady):组件外部在x(y)方向上填充的空间大小,默认单位为像素;
7.in_:将本组件作为所选组件对象的子组件,类似于指定本组件的master为选定组件;
8.sticky:组件紧靠所在单元格的某一边角,注意是单元格,而不是父widget
*********************************************************************************************
感觉pack比grid好理解,下面是用pack实现的类似qq的聊天窗口:
结果如下: