學習python的tkinter免不了要對各個組件進行位置的排放與設定,常用的布局管理器有grid,pack和place。這三種均用於同一父組件下的組件布局,但是也是有區別的,先看下他們各自的含義吧。
pack:按添加順序排列組件
grid:按行列形式排列組件
place:允許程序員指定組件的大小和位置
常用方法:這里先列出來,后文會對個方法進行說明
pack常用的方法 pack(**options) pack_configure(**options) pack_forget() pack_info() pack_propagate(flag) pack_slaves() grid常用方法 grid(**options) grid_bbox(column=None, row=None, col2=None, row2=None) grid_columnconfigure(index, **options) grid_configure(**options) grid_forget() grid_info() grid_location(x, y) grid_propagate(flag) grid_remove() grid_rowconfigure(index, **options) grid_size() grid_slaves(row=None, column=None) place常用方法 place(**options) place_configure(**options) place_forget() place_info() place_slaves() slaves()
使用說明
pack管理器使用:
pack適合於少量的組件排序,所以在使用上是相當簡單,一般添加組件后直接使用.pack()方法即可。。但是如果想要對復雜的組件進行布局,那就要使用grid()或者Frame框架。
注:同一個父組件中不能同時使用pack()和grid(),否則Tkinter會一直糾結先用哪個布局管理器,所以就卡死在糾結中了。
先來看個例子吧,是經常要用到的情況:將一個組件放到一個容器組件中,並填充整個父組件。
1 from tkinter import * 2 root = Tk() 3 listbox = Listbox(root) 4 listbox.pack(fill=BOTH,expand=True) #fill選項是填充整個父組件,expand選項是拉伸時依舊填滿 5 for i in range(10): 6 listbox.insert(END,str(i)) 7 mainloop()
執行結果:
其中,fill 選項是告訴窗口管理器該組件將填充整個分配給它的空間,BOTH 表示同時橫向和縱向擴展,X 表示橫向,Y 表示縱向。expand 選項是告訴窗口管理器將父組件的額外空間也充滿
默認下,pack 是將添加的組件一次縱向排列
1 from tkinter import * 2 root = Tk() 3 Label(root,text="red",bg="red",fg="white").pack(fill=X) #fill選項是設置橫向填充 4 Label(root,text="red",bg="green",fg="black").pack(fill=X) 5 Label(root,text="red",bg="blue",fg="white").pack(fill=X) 6 7 # Label(root,text="red",bg="red",fg="white").pack(side=RIGHT)#如果想將組件整體橫向排序,可以設置side選擇 8 mainloop()
執行結果:
grid管理器的使用
grid 管理器可以說是 Tkinter 這三個布局管理器中最靈活多變的。如果你只希望學習使用一個布局管理器,那么 grid 絕對是首選。當你在設計對話框的時候,使用 grid 尤其便捷。使用一個 grid 就可以簡單的實現你用很多個框架和 pack 搭建起來的效果。
使用 grid 排列組件,只要告訴它你想要組件放置的位置(行 / 列,row 選項指定行,column 選項指定列)。此外你並不用提前指出網格(grid 分布給組件的位置稱為網格)的尺寸,因為管理器會自動計算。
來看一個簡單的登錄界面:
1 from tkinter import * 2 root = Tk() 3 Label(root,text="用戶名:").grid(row=0,column=0) 4 Label(root,text="密 碼:").grid(row=1,column=0) 5 6 Entry(root).grid(row=0,column=1) 7 Entry(root,show="*").grid(row=1,column=1) 8 mainloop()
執行結果:
用幾個網格來放置一個組件,可以使用 rowspan 和columnspan 實現跨行跨列的功能
1 from tkinter import * 2 3 root = Tk() 4 5 Label(root, text="用戶名").grid(row=0, sticky=W) 6 Label(root, text="密碼").grid(row=1, sticky=W) 7 8 photo = PhotoImage(file="gaga.png") 9 Label(root, image=photo).grid(row=0, column=2, rowspan=2, padx=5, pady=5) 10 #rowspan選項設置了跨行,現在photo組件可以顯示0,1兩行了。padx,pady設置了邊距,使圖片文字不挨在一起11 Entry(root).grid(row=0, column=1) 12 Entry(root, show="*").grid(row=1, column=1) 13 14 Button(root,text="提交", width=10).grid(row=2, columnspan=3, pady=5) 15 16 root.mainloop()
執行結果:
place管理器使用
通常情況下不建議使用 place 布局管理器,因為對比起 pack 和 grid,place 要做更多的工作。不過存在即合理,place 在一些特殊的情況下可以發揮妙用,甚至是 pack 和 grid 無法代替。
將子組件顯示在父組件的正中間
1 from tkinter import * 2 3 root = Tk() 4 def callback(): 5 print('真的點到我了') 6 Button(root, text='點我呀', command=callback).place(relx=0.5, rely=0.5, anchor=CENTER) #relx和rely是相對父組件的位置。0是最左邊,0.5是正中間,1是最右邊 7 mainloop()
執行結果:
在某種情況下,你希望一個組件能夠覆蓋另一個組件。下面使用一個按鈕覆蓋一個Label圖片的例子
1 from tkinter import * 2 3 root = Tk() 4 photo = PhotoImage(file="gaga.png") 5 Label(root, image=photo).pack() 6 def callback(): 7 print('點到我了') 8 Button(root, text='點我', command=callback).place(relx=0.5, rely=0.5, anchor=CENTER) #relx和rely是相對父組件的位置,范圍是 00~1.0。0是最左邊,0.5是正中間,1是最右邊 9 mainloop()
執行結果:
relheight 和 relwidth 選項則是指定相對於父組件的尺寸
1 from tkinter import * 2 3 root = Tk() 4 5 Label(root, bg='red').place(relx=0.5, rely=0.5, relheight=0.75, relwidth=0.75, anchor=CENTER) #relheight和relwidth是設置調用place的子組件相對於父組件的高度和寬度 6 Label(root, bg='yellow').place(relx=0.5, rely=0.5, relheight=0.5, relwidth=0.75, anchor=CENTER) 7 Label(root, bg='green').place(relx=0.5, rely=0.5, relheight=0.25, relwidth=0.75, anchor=CENTER) 8 9 mainloop()
執行結果:
還有 x 和 y 選項用於設置偏移(像素),如果同時設置 relx(rely) 和 x(y),那么 place 將優先計算 relx 和 rely,然后再實現 x 和 y 指定的偏移值。
pack的方法
注:下面方法適用於所有組件
pack(**options) --下方詳細列舉了各個選項的具體含義和用法
選項 |
含義 |
anchor |
--控制組件在pack分配的空間中的位置 --N, NE, E, SE, S, SW, W, NW或CENTER來定位(EWSN表示東南西北) --默認值是CENTER |
expand |
--指定是否填充父組件的額外空間 --默認值是False |
fill |
--指定填充pack分配的空間 --默認值是NONE,表示保持子組件的原始尺寸 --還可以使用的值有:X(水平填充),Y(垂直填充)和BOTH(水平和垂直填充) |
in_ |
--將該組件放到該選項指定的組件中 --指定的組件必須是該組件的父組件 |
ipadx |
--指定水平方向上的內邊距 |
ipady |
--指定垂直方向上的內邊距 |
padx |
--指定水平方向上的外邊距 |
pady |
--指定垂直方向上的外邊距 |
side |
--指定組件的放置位置 --默認值是TOP --還可以設置的值有:LEFT,BOTTOM,RIGHT |
pack_configure(**options) --跟 pack() 一樣
pack_forget() --將組件從屏幕中“刪除” --並沒有銷毀該組件,只是看不到了 --可以通過 pack 或其他布局管理器顯示已“刪除”的組件
pack_info() --以字典的形式返回當前的 pack 的選項
pack_propagate(flag) --如果開啟,父組件會自動調節尺寸以容納所有子組件 --默認值是開啟(flag=True) --該方法僅適用於父組件
pack_slaves() --以列表形式返回該組件的所有子組件 --該方法僅適用於父組件
grid 的方法:
注:下邊方法適用於所有組件
grid(**options) --下面列舉了各個選項的具體含義和用法
選項 | 含義 |
column | --指定組件插入的列(0表示第一列) --默認值是0 |
columnspan | --指定用多少列(跨列)顯示該組件 |
in_ | --將該組件放到該選項指定的組件中 --指定的組件必須是該組件的父組件 |
ipadx | --指定水平方向上的內邊距 |
ipady | --指定垂直方向上的內邊距 |
padx | --指定水平方向上的外邊距 |
pady | --指定垂直方向上的外邊距 |
row | --指定組件插入的行(0表示第一行) |
rowspan | --指定用多少行(跨行)顯示該組件 |
sticky | --控制組件在grid分配的空間中的位置 --可以使用N,E,S,W以及他們的組合來定位 --使用加號(+)表示拉長填充,例如N+S表示將該組件垂直拉長填充網格,N+S+W+E表示填充整個網格 --不指定該值則居中顯示 |
grid_bbox(column=None, row=None, col2=None, row2=None)
--返回一個四元組描述該組件所在的限定矩形 --如果指定 column 和 row 參數,則返回該位置 (column, row) 的組件的限定矩形的描述
grid_columnconfigure(index, **options)
--設置列的屬性--注意:設置的是該組件所擁有的grid序列
可以設置的選項及含義如下:
選項 | 含義 |
minsize | --指定該列的最小寬度 |
pad | --指定該列中最大網格的水平邊距 |
weight | --指定列與列之間的相對距離 --默認值是0 --說明:初創建窗口的時候,grid會自動根據組件的尺寸分配窗口的尺寸,當你拉伸窗口的尺寸就會有空白顯示出來。這個選項正是指定列與列之間是否填充空白,默認是不填充的。另外,該選項的值是指定填充空白的倍數,例如weight=2的列會比weight=1的列填充多一倍的空白,所以需要平均填充的話,只需要所有的列都設置為weight=1即可。 |
grid_configure(**options) --跟 grid() 一樣
grid_forget() --將組件從屏幕中“刪除” --並沒有銷毀該組件,只是看不到了 --可以通過 grid 或其他布局管理器顯示已“刪除”的組件,但該組件所在網格的選項設置不會恢復
grid_info() --以字典的形式返回當前 grid 的選項
grid_location(x, y) --返回位於(或接近)給定坐標(x, y)的網格位置 --返回值是一個 2 元組表示網格對應的(列, 行)
grid_propagate(flag) --如果開啟,父組件會自動調節尺寸以容納所有子組件 --默認值是開啟(flag=True) --該方法僅適用於父組件
grid_remove() --跟 grid_forget() 一樣,但恢復的時候會記住該組件所在網格的選項設置
grid_rowconfigure(index, **options) --設置行的屬性 --注意:設置的是該組件所擁有的grid的行
可以設置的選項及含義如下:
選項 | 含義 |
minsize | --指定該列的最小寬度 |
pad | --指定該列中最大網格的垂直邊距 |
weight | --指定行於行之間的相對距離 --默認值是0 |
grid_size() --返回該組件所擁有的 grid 的尺寸 --返回值是一個 2 元組,表示(列,行)分別的網格數
grid_slaves(row=None, column=None) --以列表的形式返回該組件的所有子組件 --該方法僅適用於父組件
place的方法
注:下邊的方法適用於所有的組件
place(**options) --下方列舉了各個選項的含義和用法
選項 |
含義 |
anchor |
--控制組件在place分配的空間中的位置 --N, NE, E, SE, S, SW, W, NW或CENTER來定位(EWSN表示東南西北) --默認值是NW |
bordermode |
--指定邊框模式(INSIDE或OUTSIDE) --默認值是INSIDE |
height |
--指定該組件的高度(像素) |
in_ |
--將該組件放到該選項指定的組件中 --指定的組件必須是該組件的父組件 |
relheight |
--指定該組件相對於父組件的高度 --取值范圍是0.0~1.0 |
relwidth |
--指定該組件相對於父組件的寬度 --取值范圍是0.0~1.0 |
relx |
--指定該組件相對於父組件的水平位置 --取值范圍是0.0~1.0 |
rely |
--指定該組件相對於父組件的垂直位置 --取值范圍是0.0~1.0 |
width |
--指定該組件的寬度(像素) |
x |
--指定該組件的水平偏移位置(像素) --如果同時指定了relx選項,優先實現relx選項 |
y |
--指定該組件的垂直偏移位置(像素) --如果同時指定了rely選項,優先實現rely選項 |
place_configure(**options) --跟place()一樣
place_forget() --將組件從屏幕中“刪除” --並沒有銷毀該組件,只是看不到了 --可以通過 place 或其他布局管理顯示已“刪除”的組件
place_info() --以字典的形式返回當前 place 的選項
place_slaves() --以列表的形式返回該組件的所有子組件 --該方法僅適用於父組件
slaves() --跟 place_slaves() 一樣