原文来自FishC。
pack,grid,place均用于管理在一个父组件下的所有组件的布局,其中:
1)pack是按添加顺序排列组件
2)grid是按行/列形式排列组件
3)place则容忍我们指定组件的大小和位置
对比grid管理器,pack更适用于少量组件的排列,但它在使用上更加简单;如需创建相对复杂的布局结构,则建议使用多个框架(frame)构成,或者使用grid来实现;
注意:不要在同一个父组件中混合使用pack,grid;
默认下,pack是将添加的组件依次纵向排列;如果想要组件横向排列,可以使用side选项:
Label(root,text='Blue',bg='blue',fg='white').pack(side=LEFT)
灵活多变,使用一个grid就可以简单的实现使用多个框架和pack搭建起来的效果;
使用grid排列组件,只需告诉位置(row/column);默认情况下会居中显示在对应的网格中,可以使用sticky来修改这一特性,该选项可以使用的值有E,W,S,N(分别表示东南西北)以及它们的组合,如使label左对齐:
Label(root,text="User Name").grid(row=0,sticky=W)
Label(root,text="Password").grid(row=1,sticky=W)
如需几个网格来放置一个组件,可以指定rowspan,columnspan就可以实现跨行和跨列的功能,如:
photo=PhotoImage(file="log.gif")
Label(root,image=photo).grid(row=0,column=2,rowspan=2,padx=5,pady=5)
padx,pady分别指定水平,竖直方向的外边距。
通常情况下不建议使用place布局管理器,因为对比pack,grid,place要做更多的工作;
如将子组件显示在父组件的正中间:
Button(root,text="Click",command=callback).place(relx=0.5,rely=0.5,anchor=CENTER)
使用place可以实现一个组件覆盖另外一个组件,如Button覆盖Label组件:
photo=PhotoImage(file=logo_big.gif)
Label(root,image=photo).pack()
Button(root,text="Click",command=callback).place(relx=0.5,rely=0.5,anchor=CENTER)
其中relx,rely选项是指定相对于父组件的位置,范围00~1.0,因此0.5表示位于正中间,relwidth,relheight则是相对于父组件的尺寸,如:
Label(root,bg='red').place(relx=0.5,rely=0.5,relheight=0.75,relwidth=0.75,anchor=CENTER)
上面改变窗口尺寸,Label的尺寸均会跟着改变;
x和y选项用于设置偏移(pixel),如果同时设置relx/rely和x/y,那么place将会先计算relx,rely,然后再实现x,y指定的偏移值。