Tkinter中部件布局(擺放的方式)方法: pack 、 place 、 grid
有了GUI設計的內容,該如何按照我們的需要放入到基底視窗中(基底視窗就如同你設計的桌布一般)呢?這牽涉到部件布局的方式。
在我們用tkinter設計GUI過程中,應該運用哪種布局方式來安排各項部件的位置最適合呢?如何對Tkinter 所設計的多項部件作布局安排(各部件間的相對位置)?讓我們談談Tkinter提供的三種布局方法吧?
有哪三種布局方法
Tkinter提供三種方式供我們選擇,分別是:
- pack(打包-讓各個部件依pack順序由上至下、也可指定左右或特定位置放置)
- place(定位,直接指定各個部件X及Y軸之絕對或相對位置)
- grid(網格,建立欄列二維矩陣行列,並運用列row、欄column位置指定各個部件的布局)
依上面字義描述,我們不難理解這三種布局指令的邏輯,但真正的運用還得靠一些範例說明,當然最重要的是加上自己的練習。
各項佈局方法的優勢
pack最簡單,但要做複雜的對位及控制,調整對齊的難度高。
place最精準,但布局過程及布局後之調整很費心,且當基底視窗resize調動大小時,位置會走位,有些部件會被遮蔽,另外若有部件的增減,要調整各個不建的定位得經過一番努力去調整。
grid規則邏輯很清楚很統一,未來也最好調整,撰寫後之的程式也最好理解及佈局最結構化,但一般簡單的GUI布局,很多人還是習慣使用pack。
各項佈局方法的說明及範例
您習慣用哪種方式布局都好,但這三種方式請不要混合使用,除了讓未來維護困難外,程式的閱讀也很困擾,未來依視窗大小resize後產生位置錯亂的風險也很大。
接著,我們就一一介紹各種布局的方式及相關指令。
在開始以前,您需先具備運用tkinter建立使用者介面的基礎能力,若還沒涉略,可以參考運用tkinter建立第一個用戶友善介面(GUI)的基本能力這一篇。
Pack
我們先示範一個上下順序的範例,布局時需要注意
- 每一個部件都需要設定布局。
- 布局的前後順序決定它出現的位置順序,由上至下(預設)或由左至右。
我們先建立一個基底視窗,同時在視窗中建立四個label部件,我們特別忽略第四個label部件的布局,看看會有什麼效果,為了更明顯顯示,特別用不同顏色顯示不同label欄位,同時也將label2的布局晚於label3,看看結果您就了解在pack的布局方式,先後順序很重要,他會決定各部件的上下關係。
執行程式後得到的結果為
執行上述程式的結果顯示:
- 未進行布局(pack)的label4部件,將不會產生顯示的效果。
- 原先應定義為第二個欄位label2的部件,因為布局pack的順序晚於label3,使得它出現的順序晚於label3。
如果我們完整整個布局並按其應該的新後順序布局,就可發現整個視窗的顯示如同我們原來的期望。
接著,我們示範一個由左至右布局的範例:
一樣是運用四個label部件來安排,這一次我們在pack布局方法中設定side='left'的參數,意思是將這個部件依序往左放,同時也運用padx的參數設定各個部件中x軸距離5個pixel。所以依上述的程式執行後的結果為:
在pack布局方法中,除了side及padx等參數外,還有以下的參數提供給您,讓我們再用pack安排這些部件的位置時,多了一些參數方法來定義安排及調整布局。
另外,,部分這些參數也可運用在grid或place的布局方法中。
我們就用幾個例子來示範運用這些參數的效果
- label2所使用的參數fill='x',fill的參數會讓部件在您指示的x軸或y軸的大小上滿足與cell(系統依部件大小給的預設空間)等高或等寬,若參數為fill='both',則代表部件會完全在寬度及高度上充滿整個cell。
- label3所使用的參數expand='yes',表示label3這個部件會expand(擴充)它的欄寬及欄高。
- label4所使用的參數padx=10,表示label4這個部件與這個cell的邊框必須保持10個單位的pixel,可以看出這樣的使用,要求部件依您的指示在x軸線上與cell的邊寬保持10pixel距離,這樣的效果反而使得欄寬變寬了。
- label5所使用的參數 ipadx=30,i代表internal(內部),運用這個參數使得部件的text標題會與部件的外框保持30個pixel的距離,當然等同pad一般分為ipadx及ipady分別代表與部件x軸的外框及y軸外框的距離。
- label6所使用的參數 side='left',運用side的參數,讓我們對於這個部件的位置可以依需要讓從哪個方向排列,不再是依上下順序排列。
這些參數的運用確實也需要一些練習及測試,有時候真正在使用時,並非完全如我們想像預期的效果,因為它受限於基底視窗的大小及與其他部件的相對關係(如距離及大小)有關。
place
當然,我們若要將四個欄位分別置放於基底視窗的上下左右四個位置時,我們運用pack的布局方法,可以很容易達到這樣的效果。同樣的,若用place布局方法,將這四個部件'硬刻'在四個方位也可以,經過您千算萬算後,當然也可以達到精準定位的目的。
一般,place布局的方法語法總是用
place(x=數字,y=數字)即能簡單的定義部件應該坐落的絕對位置,x後跟的數字即為部件坐落的x座標(單位為pixel),y後跟的數字即為部件坐落的起始y座標(單位為pixel)。
或者也可以如下運用relx即rely依基底視窗的大小用相對的比例位置定位(如下):
place(relx=數字,rely=數字),記著,這裡的數字是介於0~1,可以是小數點,這裡的數字1代表是基底視窗的長或寬的全部,所以我們應該在1的範圍內,依我們希望坐落的百分比給予一個界於0跟1間的小數數字,x軸及y軸都是以1為全部的比例。所以relx=1 的位置是視窗的右邊框,rely=1 的位置是視窗的下邊框。
以下的範例就是用絕對位置及相對位置所定義出部件應坐落的位置。
運用place布局方法,不論是用絕對位置或相對位置,皆可以達到部件布局於您所指定的位置的目的。
但它的後遺症就是,當使用者螢幕的解析度與您設計時不同,或用戶視窗大小做調整時,您精準定位的位置可能就會失真(走位或遮蓋),另外,將您未來要加入一個部件或部件順序上做調整時,您又得將布局的定位重新安排一次,所以place布局方法,看似簡單而且精準,但卻是很難維護或缺乏改變彈性的一種方式,真的很不適宜列入在友善介面設計的方法。
以下的例子說明,我們可以用pack也可以用place達到同樣的目的,但當視窗調整時,place方法就顯示出它的缺點:
pack布局
結果
place布局
結果
感覺上,都可以達到同樣目的,但當使用者運用滑鼠調整視窗大小時,pack布局方式,欄位的配置會隨著視窗的調動(resize)而調整
但place就會出現這樣的風險:
上述的例子,只是運用place布局方法的缺點之一。
之後,我們再建議您一種布局的方法-grid,因為用pack方法,對多個部件需左右對齊或者是美觀布局時,常需先將基底視窗先切割成多的框架(frame),且有一些美觀上的設計總是有力又未逮的遺憾。基於這些理由,建議您,若您了解並熟悉grid布局的方法,對於設計使用者友善的GUI將有很大的幫助,不論在美觀上、設計的容易度及效率上、未來的維護上(增減部件及部件間調動)都很具優勢。
grid
在示範之前,grid的布局方便於對話式互動GUI的設計,因為網格的齊頭讓它很容易對齊及置放,在大部分複雜欄位的視窗設計上,不再需要將視窗切割成幾個框架(frame,frame切割有助於不同區域不同屬性部件的區隔)再將部件分門別類放入,而且每一個網格的大小,在grid的運用下,會針對置入的部件大小自動做調整,且網格是運用row及column來定位,未來在欄位的增刪調整時,程式的調整相對容易得多,這就是若您練就grid布局方式時所能帶來的好處。
既然grid是我們推薦各位要花時間學習及熟練的布局方法,所以這裡我們就用較多的欄位及圖文並茂的GUI方式來說明它的好用之處。
我們這次要設計的視窗部件規劃如下
label1 |
entry1 |
Logo image |
|
label2 |
entry2 |
||
button1 |
button2 |
button3 |
轉換成用戶使用時的視覺GUI期望是這樣
帳 號 |
資料輸入區 |
Logo image |
|
密 碼 |
資料輸入區 |
||
會員登入 |
申請會員 |
與我們聯絡 |
所以在完成這個GUI時,我們需要三個Label部件,分別是文字內容的帳號及密碼兩個標籤部件,一個是圖案logo image label,另外需要三個button部件,分別是會員登入button、會員申請button、與我們聯絡button,由於這邊說明的是grid布局,button引發的功能就不在示範的程式中說明。
程式內容如下
給予row及column數字即可決定部件的所在位置
Grid布局方法也有許多參數來定義元件的樣貌,包含大小、對齊方式、佔幾個欄寬及列長等。程式執行的結果如下
感覺上,使用grid網格式的布局,就形同將基底視窗切割成很多對齊的cell小視窗,就像window office的excel一樣,再將各部件依您的指示放入這些cell(窗格)
但每個部件要呈現的樣貌或大小及對齊的方式不盡相同,所以使用grid布局的同時可以利用以下參數來定義其位置或改變部件放入窗格中的樣子及規格。
row:定義這個部件坐落在哪一列,如row=2
volumn:定義這個部件坐落在哪一欄,如column=2
rowspan:定義這個部件跨幾列,如rowspan=2
columnspan:定義這個部件跨幾欄,如columnspan=2
padx、pady:定義部件與cell邊框的橫縱向的距離,如padx=10
ipadx、ipady:定義部件與部件間橫縱向的距離,如ipadx=5
sticky:部件預設會放置於cell的中間,這個參數幫我們指定部件往哪邊靠,如sticky='w'就是靠左,設定sticky='we'會自動將部件延展為整個cell的寬度,同樣的,設定sticky='ns'則延展為整個高度。
總結
布局方法的運用其實很簡單,多做幾個練習就更能熟悉,但它是GUI規劃及佈局不可或缺的工具。GUI設計的精神在於一開始時對於使用者友善動線的規劃及整體樣貌的藍圖企劃,不妨先在紙上畫上布局的大概,當藍圖有了之後,請您丟掉對於這項服務的既定了解,換個位置,站在您是一個陌生的訪客,在整個操作上需要那些引導及互動,這樣的設計的細節及結果才會趨於友善。grid布局方式,是我認為最容易規劃的布局方法,它的優勢是,在設計過程中之個別細節調整及未來維護調整時,它的成本最低,也不容易未來變更時,落入牽一髮而動全局的困境。
留言列表