Grid 格狀版面佈局
如果在 tkinter 裡要進行比較進階的版面編輯,會使用 grid() 方法來產生類似表格版面進行元件的放置,這篇教學會介紹如何使用 grid() 方法,並進行格狀的元件排版佈局。
快速導覽:
因為 Google Colab 不支援 tkinter,所以請使用本機環境 ( 參考:使用 Python 虛擬環境 ) 或使用 Anaconda Jupyter 進行實作 ( 參考:使用 Anaconda )。
使用 grid()
使用 tkinter 相關方法建立元件後,除了使用 pack() 方法進行基本放置 ( 參考 Pack 基本版面佈局 ),也可以使用 grid() 方法,採用類似「表格」的方式放置元件,以下方的例子而言,有四個 Label 都指向 root ( 主視窗元件 ),使用 grid() 將四個 Label 排列成 2x2 的版面。
注意,在同一個視窗元件 ( 父元件 ) 中,不能同時使用 pack() 和 grid()。
import tkinter as tk
root = tk.Tk()
root.title('oxxo.studio')
root.geometry('200x200')
a = tk.Label(root, text='AAA', background='#f90')
b = tk.Label(root, text='BBB', background='#09c')
c = tk.Label(root, text='CCC', background='#fc0')
d = tk.Label(root, text='DDD', background='#0c9')
a.grid(column=0, row=0) # 放在 (0,0)
b.grid(column=1, row=0) # 放在 (1,0)
c.grid(column=0, row=1) # 放在 (0,1)
d.grid(column=1, row=1) # 放在 (1,1)
root.mainloop()
column、row 參數
grid() 的 column 和 row 參數表示放置的元件位置,column 表示水平方向,左上角起始為 0,row 表示垂直方向,左上角起始為 0,同一個視窗元件 ( 父元件 ) 中只能使用一個 grid,放置後會根據所有元件的 column 和 row 產生對應的表格佈局,以上方的例子為例,會產生 2x2 的佈局,如果使用下方的程式碼,則會產生 3x2 的佈局 ( 因為只有四個元件,所以有兩格會留空 )。
import tkinter as tk
root = tk.Tk()
root.title('oxxo.studio')
root.geometry('200x200')
a = tk.Label(root, text='AAA', background='#f90')
b = tk.Label(root, text='BBB', background='#09c')
c = tk.Label(root, text='CCC', background='#fc0')
d = tk.Label(root, text='DDD', background='#0c9')
a.grid(column=0, row=0) # 放在 (0,0)
b.grid(column=2, row=0) # 放在 (2,0)
c.grid(column=0, row=1) # 放在 (0,1)
d.grid(column=1, row=1) # 放在 (1,1)
root.mainloop()
columnspan、rowspan 參數
如果要讓「多格可以合併成一格」,可以使用 columnspan 或 rowspan 參數,參數預設值為 1,若設定大於 1 的數字表示要合併幾格。
import tkinter as tk
root = tk.Tk()
root.title('oxxo.studio')
root.geometry('200x200')
a = tk.Label(root, text='AAA', background='#f90')
b = tk.Label(root, text='BBB', background='#09c')
c = tk.Label(root, text='CCC', background='#fc0')
d = tk.Label(root, text='DDD', background='#0c9')
e = tk.Label(root, text='EEE', background='#ccc')
a.grid(column=0, row=0, columnspan=2)
b.grid(column=2, row=0, rowspan=2)
e.grid(column=0, row=1, columnspan=2)
c.grid(column=0, row=2)
d.grid(column=1, row=2)
root.mainloop()
padx、pady、ipadx、ipady 參數
grid() 的 padx 參數表示左右外邊距,pady 表示上下外邊距,ipadx 表示左右內邊距,ipady 表示上下內邊距,四個參數預設值均為 0,下方的程式碼執行後,會表現出不同參數設定的結果。
import tkinter as tk
root = tk.Tk()
root.title('oxxo.studio')
root.geometry('200x200')
a = tk.Label(root, text='AAA', background='#f90')
b = tk.Label(root, text='BBB', background='#09c')
c = tk.Label(root, text='CCC', background='#fc0')
d = tk.Label(root, text='DDD', background='#0c9')
e = tk.Label(root, text='EEE', background='#ccc')
a.grid(column=0, row=0, padx=20)
b.grid(column=1, row=0, pady=20)
c.grid(column=0, row=1, ipadx=20)
d.grid(column=1, row=1, ipady=20)
root.mainloop()
sticky 參數
grid() 的 sticky 參數會元件放置的位置,設定方式預設有四個:tk.W 右邊、tk.E 左邊、tk.N 上面、tk.S 下面,除了上下左右,也可使用「+」號連結,例如 tk.E+tk.N 表示放在左上,tk.S+tk.N+tk.W 表示靠右垂直置中,下方的程式碼執行後,會表現出不同參數設定的結果。
import tkinter as tk
root = tk.Tk()
root.title('oxxo.studio')
root.geometry('200x200')
a = tk.Label(root, text='AAA', background='#f90')
b = tk.Label(root, text='BBB', background='#09c')
c = tk.Label(root, text='CCC', background='#fc0')
d = tk.Label(root, text='DDD', background='#0c9')
e = tk.Label(root, text='EEE', background='#ccc')
a.grid(column=0, row=0, sticky=tk.W+tk.S)
b.grid(column=1, row=0, ipady=20)
c.grid(column=0, row=1, sticky=tk.E+tk.N)
d.grid(column=1, row=1, ipady=20)
e.grid(column=0, row=2, ipadx=20)
root.mainloop()
同時使用 pack() 和 grid()
因為在同一個視窗元件 ( 父元件 ) 中,不能同時使用 pack() 和 grid(),所以如果要同時使用,必須搭配 frame 來進行放置,下方的例子會將 abcd 四個 Label 元件使用 grid 的方式放在一個 Frame 元件中,再將這個 Frame 與另外一個 Label 放在 root 視窗裡。
import tkinter as tk
root = tk.Tk()
root.title('oxxo.studio')
root.geometry('200x200')
frame = tk.Frame(root)
frame.pack()
a = tk.Label(frame, text='AAA', background='#f90')
b = tk.Label(frame, text='BBB', background='#09c')
c = tk.Label(frame, text='CCC', background='#fc0')
d = tk.Label(frame, text='DDD', background='#0c9')
a.grid(column=0, row=0)
b.grid(column=1, row=0)
c.grid(column=0, row=1)
d.grid(column=1, row=1)
e = tk.Label(root, text='EEE', background='#ccc')
e.pack()
root.mainloop()
意見回饋
如果有任何建議或問題,可傳送「意見表單」給我,謝謝~