1. 程式人生 > >用tkinter.pack設計複雜介面佈局

用tkinter.pack設計複雜介面佈局

對程式設計師來說,介面設計的實現,要解決的一個主要問題就是如何根據介面設計的需求,將元件以規定的大小放置在規定的位置。tkinter是python語言中常用的介面實現模組,其中pack()方法,可建立浮動,自動伸縮擴充套件的軟體介面,如以下介面。

如果你對以上用tkinter.pack實現的介面佈局有興趣,覺得有些實現效果可以參考借鑑,請繼續閱讀下面的內容。

一. pack的元件空間佈局原理分析

用pack進行的佈局介面元件,可用以下一些介面佈局空間來進行分析

side = top 的佈局空間

side = left 的佈局空間

1. 容器可用空間 

系統嚴格按程式碼的前後組織順序依次排列元件,前輩元件還沒有佔據的空間,是當前元件的可用空間,pack佈局是在當前元件的可用空間內進行的。如上圖的黑邊白底的區域。(為了說明,我留出padding空間,若沒有padding,元件將佔據整個目前可用空間)

2.元件原始大小可見空間

設定了width, height, 或由具體內容確定的元件原始大小,也就是可以看得見的元件寬高。如上圖的黃色區域。

3.元件的獨佔空間

元件不單隻佔據它原始可見的位置,而是會同時佔據可用空間的整行空間或整列空間。如上圖紅色區域。

side = top / bottom 時,元件佔據整行,後輩元件只能依次排在它的下面 / 上面;元件為上下排列方式

side = left / right 時, 元件佔據整列,後輩元件只能依次排在它的右邊 / 左邊;元件為左右排列方式

pack() , 我分析下來,其實就是 pack(side=top)

元件獨佔空間,沒有進行填充(fill)時,不可見,但我們必須瞭解到它的存在,因為它直接影響元件本身及後輩元件的佈局。

元件獨佔空間,是固有的,其它後輩元件絕對不可能進入該空間,後輩元件最多隻能緊靠它。

4. 元件可擴充套件空間

元件獨佔空間的另一個方向,是元件的可擴充套件空間方向。如上圖的淺藍色區域。

side = top / bottom 時,元件獨佔整行,並可向整列方向進行擴充套件。

side = left / right 時,元件獨佔整列,並可向整行方向進行擴充套件。

元件可擴充套件空間,沒有進行填充(fill)時,也是不可見的,但它同樣會直接影響自身和後輩元件的佈局,必須掌握它的空間存在。

若設定了 expand = yes, 則啟用可擴充套件空間;若 expand = no, 則不啟用可擴充套件空間。

元件可擴充套件空間,是動態的,是可以被後輩元件的獨佔空間佔據壓縮的,後輩元件可以從前輩可擴充套件空間的邊緣開始入侵,直至壓縮到前輩元件自身的獨佔空間為止。 

5. 元件佔用總空間

元件獨佔空間 + 元件可擴充套件空間,就是當前元件的總佔用空間,若沒有啟用元件擴充套件空間(expand = no),則只包含元件獨佔空間。

接下來的 錨定位(anchor)和填充(fill),都是基於元件的佔用總空間來進行處理的。

6. 空間定位和填充

錨定位(anchor ),加 padx, pady , 可將元件安排在指定位置

錨定位有9個方向,預設為 center, 居中

若 side = top / bottom ,  expand=no, 則合併到一行,即NW, W, SW的效果一樣,其他同理。

若 side = left / right,  expand = no, 則合併到一列,即NW, N, NE的效果一樣,其他同理

填充(fill)元件,可以將元件的可見,可操作範圍充滿指定區域

填充的方式有4種,預設的方式是(none),不填充。

二. 單元件佈局的分析步驟

以上描述的pack佈局原理,需要仔細理解和掌握,這是pack佈局的基礎,當我們理解這些原理後,就可以用來控制單個元件的位置了。

基本分析步驟為:

1. 明確當前容器的可用空間範圍

2.分析是用上下排列方式(side=top / bottom),還是左右排列方式(side=left/right)

3.分析是否需要啟用擴充套件空間,若需要則設定 expand = yes, 否則保持預設值 expand = no

4.利用錨定位(anchor),確定元件的具體位置

5.利用填充(fill), 對元件的可見區域進行填充

舉例分析

設定程式碼

佈局效果

說明

.pack(side=‘top‘)

獨佔整行,預設居中

.pack(side='top', anchor='sw')

沒有啟用可擴充套件空間,只獨佔行,錨定位 nw, w, sw 都一樣,定位在西邊

.pack(side='top', expand='yes', anchor='sw')

啟用可擴充套件空間,除了獨佔的行空間,還擴充套件到了容器可用空間的所有列空間,錨定位'sw' ,定位到了容器的西南邊

.pack(side='top', expand='yes')

啟動擴充套件空間,沒有設定anchor,則預設居中(整個元件佔用空間的中間,不同於第1個例子)

.pack(side='top', expand='yes', fill='y')

啟用擴充套件空間,定位完後,進行“y”軸方向的填充,填滿整個佔用空間的列

.pack(side='top', fill='y')

沒有啟用擴充套件空間,當選擇進行“y”方向填充時,也只是在獨佔的行空間內進行“y”方向填充

三.  多元件佈局的分析

我們現在基本掌握了單個元件的佈局定位分析方法,而實際的軟體介面,一定是多元件的綜合佈局,涉及多元件之間的相互關係和影響。以上所有講到的單元件佈局分析,都有一個前提,就是在已知容器可用空間的前提下, 進行當前元件的佈局定位。

整理分析多元件佈局的要點

1. 所有元件按程式碼的前後組織次序,依次進行佈局定位

2. 設定side = top / bottom 的元件,為上下排列的元件,獨佔當時可用空間的整行 

3. 設定side = left / right 的元件,為左右排列的元件,獨佔當時可用空間的整列

4. 後輩元件不可進入任何前輩元件的獨佔空間,不論 side的設定如何,是否相同,一律都是前輩

5. 元件可擴充套件空間,是動態的,是可以被後輩元件的獨佔空間佔據壓縮的,後輩元件可以從前輩可擴充套件空間的邊緣開始入侵,直至壓縮到前輩元件自身的獨佔空間為止

6.後輩元件的擴充套件空間,不能侵佔前輩元件的擴充套件空間;既若擴充套件空間重疊,前輩享用擴充套件空間

7. 若整個介面空間縮小,出現後輩元件獨佔空間跟前排元件獨佔空間重疊時,後輩元件將被壓縮,直至消失。

8. 若介面空間繼續縮小,小到比元件獨佔空間小時,元件將被壓縮,直至消失。

9. 空間優先級別為:介面空間 > 前輩元件獨佔空間 > 後輩元件獨佔空間 > 前輩元件可擴充套件空間 > 後輩元件可擴充套件空間

10.可利用frame的多層巢狀,進行靈活佈局

舉例分析:

設定程式碼

佈局效果

說明

1.pack(side='left', expand='no', anchor='w', fill='y', padx=5, pady=5) 2.pack(side='top') 3.pack(side='right') 4.pack(side='bottom')

塊1:

第一個元件,可用空間為整個介面空間,靠左,獨佔列,不啟動擴充套件空間,按“y”方向填充,周圍有5個畫素的padding

塊2:

可用空間從塊1的右邊緣開始,靠上,獨佔行,位置居中,但注意是從塊1右邊緣到介面邊緣的中間位置,而不是整個介面的中間位置

塊3:

靠右,居中;其上下可用空間大小是塊2的下邊緣,到介面邊緣

塊4

靠下,居中;其左右可用空間大小是從塊1的右邊緣 到 塊3的左邊緣

1.pack(side='left', expand='yes', fill='x') 2.pack(side='top') 3.pack(side='right', expand='yes', fill='x') 4.pack(side='bottom')  

這個例子比較複雜點

塊1:

啟用了擴充套件空間,往“x”行方向填充,但被塊2,塊3,塊4的獨佔空間壓回到了現在的大小。

塊2:

同上,始終位於塊1右邊緣和介面邊界的中間靠上位置

塊3:

啟用了擴充套件空間,但也越不過塊4的獨佔列空間

塊4:

始終位於塊1,塊3的中間位置靠下

1.pack(side='left', expand='no', fill='y') 2.pack(side='top', fill='x') 3.pack(side='right', expand='yes', fill='both')

一個很常規的導航介面設定

塊1:導航欄

靠左,上下填充,不可擴充套件

塊2:標題欄

靠上,左右擴充套件

塊3:內容欄

位置無所謂,全面擴充套件填充

四. 程式碼演示

我寫了一個佈局演示程式,包含文章開頭展示的介面,可以對照介面實際效果和具體程式碼,來了解實現的細節。另外提供了單元件和多元件的演示工具,可以調整設定,觀察效果,來理解和掌握pack佈局的基本方法。演示程式中還包括一些其它窗體佈局和實現的方法,希望對大家有幫助。

原始碼位置