當我們需要引導用戶去在某一類別中挑選某一個功能項目時,會提供一些項目清單供用戶選擇,就好像菜單一般,當客戶翻到義大利麵類時,下方總會提供歸類為義大利麵但內容不同的各種義大利麵供客戶選擇。
當然,除了選擇項目的用途外,功能選擇也可以用這種方式歸納,除了在使用者容易找尋外,也不會讓眾多的功能選擇散落各處並太佔篇幅影響到UI的設計,就好像我們在微軟的word工具上左上方檔案、常用等項目的設計概念一般,您可以在檔案類別中選擇新增檔案、儲存檔案、另存新檔等…。所以運用選單(menu)部件,提供選擇性項目供用戶選擇,就是一個在UI設計選單部件時的不或缺的方便部件。
在tkinter中,menu(項目)部件及menubutton(選單按鈕)部件通常會結合一起使用,以達到運用menubutton建立一個選單按鈕並在這個按鈕下建立一些menu可選擇項目供使用者挑選。當然,單單運用menu部件也可以達到同樣的功能,但因為menu部件被定義為視窗等級的部件,只用menu產生的選單物件只能出現在你基底視窗的左上角,而沒辦法讓您任意擺放。所以,在我個人在使用的經驗中,同時運用menu及menubutton這兩種部件的結合是最容易教學及是最直覺易懂的方式。
我們就在章節開始時大約說明建立選單物件的整個流程:
- 產生一個選單按鈕物件menubutton1,選單按鈕的名稱叫『編輯』。
產生menubutton(選單按鈕)部件的語法:
選單按鈕物件(自訂名稱) = tk.Menubutton ( 基底視窗, option, ... )
menubutton1=tk.Menubutton(window,text='編輯')
這樣就可以建立一個選單按鈕物件memubutton1,但是,光有按鈕沒有選單項目將無法滿足一個完整選單的內容,所以接著,我們要建立一個選單物件(menu),再將它定義為menubutton1之選單。
- 產生一個選單物件menubutton_menu,並定義此選單歸屬於選單按鈕memubutton1。
產生menu(選單)部件的語法:
選單物件(自訂名稱) = tk.Menu ( 定義屬於哪個選單按鈕物件, option, ... )
menubutton1_menu=tk.Menu(menubutton1,tearoff=0)
其中tearoff的選單物件屬性的功能是此選單可讓使用者撕開並獨立置放於左上角,由於這樣的功能極少被用到,同時也會讓選單多一行虛線橫列,故我們可以將屬性設定為tearoff=0以避免虛橫線的出現。
- 運用布局方法grid,定位menubutton1出現在基底視窗的左上角開始的位置,並運用config函式來改變剛剛產生menubutton1物件時,沒有定義的選單物件參數。
menubutton1.grid():其中括符中沒有定義任何值即代表row=0 column=0 就是代表此物件置於基底視窗中最開端的位置。
menubutton1.config(menu=menubutton1_menu):改變menubutton1之前沒有定義的屬性,也就是賦予選單按鈕物件menubutton1的選單menu設定為menubutton1_menu。
- 為您的選單物件menubutton1_menu增加選單項目
menubutton1_menu.add_command(label='複製')
menubutton1_menu.add_command(label='貼上')
add_command為選單物件常用的一個成員函式,它的目的式建立選單內的項目,在本例子中,我們增加了一個『複製』可選擇項目及一個『貼上』可選擇項目。
另一個add_seperator函式,可用來產生可以區隔不同選單類型的區隔線,後面的例子會運用到。
整個程式完整的內容如下:
執行後的結果如下:
因為很多的較完整的選單通常不會只有一個選單按鈕項目,所以我們接著繼續練習下去。
- 我們繼續增加一個選單按鈕menubutton2,選單按鈕名稱叫『檔案』
menubutton2=tk.Menubutton(window,text='檔案')
同樣的,我們也為這個選單按鈕設計了一個menubutton2_menu選單物件
menubutton2_menu=tk.Menu(menubutton2,tearoff=0)
運用grid方法布局時,第二個選單按鈕我們定義在第一個選單按鈕的右邊,所以是同列不同行,所以給予column=1
menubutton2.grid(row=0,column=1)
同樣的,我們運用config函式來改變剛剛產生menubutton2物件時,沒有定義的選單物件參數menu。
menubutton2.config(menu=menubutton2_menu)
- 接著為您的選單物件menubutton2_menu增加選單項目
menubutton2_menu.add_command(label='開啟')
menubutton2_menu.add_command(label='列印')
menubutton2_menu.add_separator()
這就是我們前面提到的區隔橫線的成員函式,執行後您就可以看到它的用途
menubutton2_menu.add_command(label='關閉')
整個程式增加的內容如下:
行後的結果如下:
這樣的選單完整度是不是就接近一般我們常用的完整選單型態。
但是大部分複雜一些的選單中,在選單項目下常又有選單,所以接下來,我們試一下在選單項目下再包含選單的實作。
- 建立選單中再有選單的做法
我們在剛剛的選單中增加一個存檔的選單項目,並在這個『存檔』的選單項目下建立兩個選擇項,一個為『原檔覆蓋』,另一個為『另存新檔』。
先建立一個menubutton2_menu_menu的選單物件,建立時定義此選單物件附屬於menubutton2_menu選單
menubutton2_menu_menu=tk.Menu(menubutton2_menu,tearoff=0)
add_cascade為選單物件的一個成員函式,它的目的是將我們新增的子選單掛在母選單物件的一個選單項下,並給予一個名稱建立一個母選單項目。在這裡,我們運用add_cascade函式,在原本menubutton2_menu的選單項目中新增一個『存檔』的選單項目,並且建立一個附屬於『存檔』選單項下的menubutton2_menu_menu選單。
menubutton2_menu.add_cascade(label='存檔',menu=menubutton2_menu_menu)
接著,運用add_command函式為您的menubutton2_menu_menu選單物件增加選單項目
menubutton2_menu_menu.add_command(label='原檔覆蓋')
menubutton2_menu_menu.add_command(label='另存新檔')
程式增加的內容如下:
執行後的結果如下:
這樣的一路介紹,我們在這邊做個歸納,在運用tkinter建立一個選單的程序大致如下:
- 建立選單按鈕物件
- 針對這個選單按鈕下所要呈現的選單建立相對應的選單物件
- 運用布局方法,您最好選擇grid方法布局
- 將各項選單選項加入於選單物件中
- 若有選單中的選單,您可運用add_cascade建立選單項目並建立這個項目下的子選單
學習到這邊,聰明如你一定會想到,既然add_cascade可以用來增加選單中的選單,難道我們不能只用 menu物件而不用menubutton來建立一個選單物件呢?答案是,可以的。所謂條條道路通羅馬,前面的示範,個人認為在理解上比較容易,但實務做法,您也可以只用menu物件就完成一個複雜的選單建立,但僅止於能建立在基底視窗等級的選單,意即出現於最左上角的選單,基礎建立在運用add_cascade建立選單項目及選單加掛。下面的範例,提供您繼續研究。
完整的程式內容如下:
程式執行的結果如下:
如果您觀察跟體驗這兩種寫法所產生的結果後,細心的您應該會發現在用戶感受面上還是有一點點的不一樣,但也就是這一點點的不一樣讓我們不得不選擇用後者menu中有menu的方式完成這項任務較為適合,您應該注意到,用menubutton實作的選單基本上是一個一個獨立的選單按鈕,也就是滑鼠指標橫移時,跨越不同選單按鈕時,部會產生自動列示下展選項的服務,必須在另一個選單按鈕按下滑鼠,才會展開下拉選項,所以經過這兩種不同物件所完成的選單其特性也不同,我在介紹時,特意先介紹menubutton的目的,是讓初學者先建立認識menubutton及menu的物件,再進入menu中有menu的較複雜邏輯中。
本章節最後,我們總結menu與menubutton用途的差異:
- 正規做法上,建立一個基底視窗左上角的選單(可以稱為視窗等級的選單),我們會用menu物件來實作。您應該有發覺用menu物件後,並不需要運用任何的布局方法部局(pack、place、grid),原因是,menu基本上屬於視窗本體的物件,產生後視窗會自動安排產生於是窗框左上角的位置。
- 建立多層選單的方法(選單中有選單),運用menu物件的add_cascade成員函式,要有幾層就又幾層,且設計出來後,滑鼠滑過後自動會列式選單選項。
- Menubutton較適合於建立在基底視窗內,有選單按鈕並列式選單項目的服務,通常就是一層的選單按鈕。
留言列表