tk是一款轻量级的GUI框架,它能够快速编写GUI程序,python自带的GUI包Tkinter也是基于tk的。在诸如一些工程软件二次开发或者python创建图形界面时,应用都比较广泛。
使用tk的常规步骤是:先创建widgets,然后利用place, pack, 或者grid命令进行布局,其中pack和grid是最常用的两种命令。今天我们聊一下pack命令的关键参数,运行原理,和使用场景。
1.关键参数
side :组件的排布方式,值:left, top, right, bottom
anchor:组建的锚定/对齐方式,tk中的值为:n(north,上边),s(south,下边),w(west,左边),e(east,右边),nw(northwest,左上角),ne(northeast,右上角),sw(southwest,左下角),se(southeast,右下角),center(中心)等;Tkinter中的值为:N, E,S,W,CENTER,含义不再赘述。
expand, fill,padx/pady等对布局方式影响较小的命令,这里不做讨论。
2.运行原理
运行原理可以用一段话总结:pack按照语句的先后顺序进行执行,依照side命令进行排布,依照anchor进行锚定或者对齐,side缺省值是top,anchor的缺省值是center,但会受到side影响。
#创建独立窗口set base [toplevel .mywin];
#创建一个frame作为容器set mainframe [frame $base.mainframe -bg gray]
pack $mainframe -padx 10 -pady 10 -expand 1 -fill both
#创建按钮组件foreach i [list 1 2 3 4] {
set btn$i [button $mainframe.btn$i -text "Button$i" -width 20]
}
#pack布局pack $btn1 -side left ;# 第一步packpack $btn2 -side top ;# 第二步packpack $btn3 -side left ;# 第三步packpack $btn4 -side right ;#第四步pack
得到的界面是下面这样的:
可以看到,pack根据每句命令执行细节和效果是这样的:
第一步:在pack Button1时,首先按side=left的布局方式进行,从左至右排布组件,就是按照图中红色框架进行了一次布局划分。由于Button1宽度固定,在不定义anchor时,其位置按照side参数排布在最左边,效果相当于anchor=w。
第二步:pack Button2时,在第一步划分布局基础上,在右边剩余空间按照side=top方式,像图中蓝色框架所示从上向下的执行了一次布局划分,同理,anchor虽然没有定义,但是效果相当于anchor=n
第三步:pack Button3时,在第二部划分基础上,在右下部剩余空间进行了一次从左向右的布局划分,如绿色框架所示。
第四步:pack Button4时,side=right,并没有颠覆第三步的从左右横向的布局,只是从右向左开始布局,如黄色框架所示,效果相当于anchor=e。
由于在mainframe中设置了expand=1允许扩展,所以窗口大小变化时,mainframe中的组件排布会发生移动,但button本身尺寸固定,其实本质是pack布局后的剩余空间大小在变化,就是图中剩下的空白黄色框。
当然我们也可以在pack时定义不同的anchor,但必须是有效的值,例如对于Button2,anchor=nw/w/ne/e/sw/se都是可以调整其位置的,但是anchor=s是没有效果的,并且nw/sw效果只等于w,ne/se效果只等于e。
3.使用场景
通过上面的分析,可以看到pack布局方式适合单调的布局,从左至右,或者自上而下,不能像grid一样产生规则的矩阵式布局。所以使用时通常有以下要点:使用frame容器布局,frame容器可以弥补pack布局的不足,使用时frame内部使用一种pack布局,外部frame使用另一种pack布局,可以产生更容易控制的效果。
对于一些特殊的布局,pack命令比grid更加简洁高效,pack不用像grid一样采用row/column定位,也不用使用rowspan/columnspan进行合并定位,pack的side和anchor更加形象直观。