控件布局
这段时间用tkinter做些简单的GUI界面,这就涉及到布局问题。tkinter 提供了三种常用的布局管理器,分别是 pack()、grid() 以及 place(),三种方法各有特点,整体来说pack()按照控件的添加顺序其进行排列最简单,但不够灵活,place()可以指定组件大小以及摆放位置,太过灵活,使用起来需要计算,并不方便,grid()以行和列(网格)形式对控件进行排列,灵活又不失简便。
grid()
grid() 函数是一种基于网格式的布局管理方法,相当于把窗口看成了一张由行和列组成的表格。当使用该 grid 函数进行布局的时,表格内的每个单元格都可以放置一个控件,从而实现对界面的布局管理。
常用的属性如下:
属性 | 说明 |
column | 控件位于表格中的第几列,窗体最左边的为起始列,默认为第 0 列 |
columnsapn | 控件实例所跨的列数,默认为 1 列,通过该参数可以合并一行中多个领近单元格。 |
ipadx,ipady | 用于控制内边距,在单元格内部,左右、上下方向上填充指定大小的空间。 |
padx,pady | 用于控制外边距,在单元格外部,左右、上下方向上填充指定大小的空间。 |
row | 控件位于表格中的第几行,窗体最上面为起始行,默认为第 0 行。 |
rowspan | 控件实例所跨的行数,默认为 1 行,通过该参数可以合并一列中多个领近单元格。 |
sticky | 设置控件位于单元格那个方位上,参数值和 anchor 相同,若不设置该参数则控件在单元格内居中。 |
表格中的每一行的高度,以这一行最高组件为基准。
表格中的每一列的宽度,以这一列最宽组件为基准。
示例
import tkinter as tk
m = tk.Tk()
m.title("tkinter widgets")
m.geometry('480x180')
m.resizable(0, 0)
lb = tk.Label(text='Select the Items', font=('times', 15, 'bold'), fg='#CD7054')
lb.grid(row=0, column=2, columnspan=4)
CheckVar1 = tk.IntVar()
CheckVar2 = tk.IntVar()
CheckVar3 = tk.IntVar()
CheckVar4 = tk.IntVar()
# variable
check1 = tk.Checkbutton(m, text="c", font=('times', 12, 'bold'), variable=CheckVar1, onvalue=1, offvalue=0)
check2 = tk.Checkbutton(m, text="c++", font=('times', 12, 'bold'), variable=CheckVar2, onvalue=1, offvalue=0)
check3 = tk.Checkbutton(m, text="java", font=('times', 12, 'bold'), variable=CheckVar3, onvalue=1, offvalue=0)
check4 = tk.Checkbutton(m, text="python", font=('times', 12, 'bold'), variable=CheckVar4, onvalue=1, offvalue=0)
#
# check1.select ()
# check1.pack(side=tk.LEFT, padx=10)
# check2.pack(side=tk.LEFT, padx=10)
# check3.pack(side=tk.LEFT, padx=10)
# check4.pack(side=tk.LEFT, padx=10)
check1.grid(row=1, column=0, columnspan=2)
check2.grid(row=1, column=2, columnspan=2)
check3.grid(row=1, column=4, columnspan=2)
check4.grid(row=1, column=6, columnspan=2)
list = []
def allSelect():
check1.select()
check2.select()
check3.select()
check4.select()
def unSelect():
check1.deselect()
check2.deselect()
check3.deselect()
check4.deselect()
def Set():
global list
list.clear()
if CheckVar1.get() == 1:
list.append('c')
if CheckVar2.get() == 1:
list.append('c++')
if CheckVar3.get() == 1:
list.append('java')
if CheckVar4.get() == 1:
list.append('python')
print(list)
allSelect = tk.Button(m, text='allSelect', font=('times', 12, 'bold'), fg='green', command=allSelect)
allSelect.grid(row=2, column=2, columnspan=2)
unSelect = tk.Button(m, text='unSelect', font=('times', 12, 'bold'), fg='red', command=unSelect)
unSelect.grid(row=2, column=4, columnspan=2)
btnSet = tk.Button(m, text='Apply', font=('times', 12, 'bold'), fg='blue', command=Set)
# btnSet.pack(side=tk.LEFT, padx=10)
btnSet.grid(row=3, column=3, columnspan=2)
m.mainloop()
横平竖直的,但是都挤到一块了,使用padx,pady参数设置控件间的间距。开始使用pack(),发现几乎不可实现多行多列控件的排布。
改进
如前所述,padx,pady参数可以设置控件间的间隔,具体的值可以是一个标量值,也可以是一个元组。如padx = 10,则该控件与左右两边的控件间距均+10,padx =(10,0)则与左边控件间距+10,右边不变。
import tkinter as tk
m = tk.Tk()
m.title("tkinter widgets")
m.geometry('480x180')
m.resizable(0, 0)
lb = tk.Label(text='Select the Items', font=('times', 15, 'bold'), fg='#CD7054')
lb.grid(row = 0, column= 2, columnspan=4,sticky=tk.N,pady=5)
CheckVar1 = tk.IntVar()
CheckVar2 = tk.IntVar()
CheckVar3 = tk.IntVar()
CheckVar4 = tk.IntVar()
# variable
check1 = tk.Checkbutton(m, text="c", font=('times', 12, 'bold'), variable=CheckVar1, onvalue=1, offvalue=0)
check2 = tk.Checkbutton(m, text="c++", font=('times', 12, 'bold'), variable=CheckVar2, onvalue=1, offvalue=0)
check3 = tk.Checkbutton(m, text="java", font=('times', 12, 'bold'), variable=CheckVar3, onvalue=1, offvalue=0)
check4 = tk.Checkbutton(m, text="python", font=('times', 12, 'bold'), variable=CheckVar4, onvalue=1, offvalue=0)
#
# check1.select ()
# check1.pack(side=tk.LEFT, padx=10)
# check2.pack(side=tk.LEFT, padx=10)
# check3.pack(side=tk.LEFT, padx=10)
# check4.pack(side=tk.LEFT, padx=10)
check1.grid(row= 1, column= 0, columnspan=2,padx = 30,pady = 10)
check2.grid(row=1, column=2, columnspan=2,padx = 30,pady = 10)
check3.grid(row=1, column=4, columnspan=2,padx = 30,pady = 10)
check4.grid(row=1, column=6, columnspan=2,padx = 30,pady = 10)
list = []
def allSelect():
check1.select()
check2.select()
check3.select()
check4.select()
def unSelect():
check1.deselect()
check2.deselect()
check3.deselect()
check4.deselect()
def Set():
global list
list.clear()
if CheckVar1.get() == 1:
list.append('c')
if CheckVar2.get() == 1:
list.append('c++')
if CheckVar3.get() == 1:
list.append('java')
if CheckVar4.get() == 1:
list.append('python')
print(list)
allSelect = tk.Button(m, text='allSelect', font=('times', 12, 'bold'), fg='green', command=allSelect)
# allSelect.pack(side=tk.BOTTOM, padx=10)
allSelect.grid(row=2, column=2, columnspan=2, pady=(0, 20))
unSelect = tk.Button(m, text='unSelect', font=('times', 12, 'bold'), fg='red', command=unSelect)
unSelect.grid(row=2, column=4, columnspan=2, pady=(0, 20))
btnSet = tk.Button(m, text='Apply', font=('times', 12, 'bold'), fg='blue', command=Set)
# btnSet.pack(side=tk.LEFT, padx=10)
btnSet.grid(row=3, column=3, columnspan=2, ipadx=20)
m.mainloop()
运行结果如下,舒服多了:
引用
参考文章叙述很详细,示例也不错o( ̄▽ ̄)d
tkinter的grid布局定位方式图示详解Tkinter布局管理器(三种方法详解