菜單Menu設(shè)計(jì)的基本概念
窗口中一般有菜單設(shè)計(jì)有鹿,菜單是一種下拉式窗體旭旭,在這種窗體中可以設(shè)計(jì)菜單列表。建立
菜單的方法是Menu()葱跋,它的語(yǔ)法格式如下持寄。
Menu(父對(duì)象,options,···)
Menu()方法的第一個(gè)參數(shù)是父對(duì)象,表示這個(gè)菜單將建立在哪一個(gè)父對(duì)象內(nèi)娱俺。下列是Menu()
方法內(nèi)其他常用的options參數(shù)稍味。
(1)activebackground:當(dāng)光標(biāo)移至此菜單列表上時(shí)的背景色彩。
(2)activeborderwidth:當(dāng)被鼠標(biāo)選取時(shí)它的外邊框厚度矢否,默認(rèn)是1.
(3)activeforeground:當(dāng)光標(biāo)移至菜單列表上時(shí)的前景色彩仲闽。
(4)bd:所有菜單列表的外邊框厚度脑溢,默認(rèn)是1僵朗。
(5)bg:菜單列表未被選取時(shí)的背景色彩。
(6)cursor:當(dāng)菜單分離時(shí)屑彻,鼠標(biāo)光標(biāo)在列表時(shí)的外觀验庙。
(7)disabledforeground:菜單列表是DISABLED時(shí)的顏色。
(8)font:菜單列表文字的字形社牲。
(9)fg:菜單列表未被選取時(shí)的前景色彩粪薛。
(10)image:菜單的圖標(biāo)。
(11)tearoff:菜單上方的分隔線搏恤,這是一個(gè)虛線線條违寿,有分隔線時(shí)tearoff值為T(mén)rue或1,此時(shí)
菜單列表從位置1開(kāi)始防止熟空,同時(shí)可以讓菜單分離藤巢,分離方式是開(kāi)啟菜單后單擊分隔線。如果將
tearoff設(shè)為False或0時(shí)息罗,此時(shí)不會(huì)顯示分隔線掂咒,也就是菜單無(wú)法分離,但是菜單列表將從位置0
開(kāi)始存放。
下列是其他相關(guān)的方法绍刮。
(1)add_cascade():建立分層菜單温圆,同時(shí)讓此子功能列表與父菜單建立鏈接。
(2)add_command():增加菜單列表孩革。
(3)add_separator():增加菜單列表的分隔線岁歉。
樣例:建立最上層的菜單列表,單擊"Hello!"會(huì)出現(xiàn)"歡迎使用菜單"的對(duì)話框膝蜈,單擊"Exit!"
則程序結(jié)束刨裆。
from tkinter import *
from tkinter import messagebox
def hello():
messagebox.showinfo("Hello","歡迎使用菜單")
root=Tk()
root.title("ch16_1")
root.geometry("300x180")
menubar=Menu(root)
menubar.add_command(label="Hello",command=hello)
menubar.add_command(label="Exit",command=root.destroy)
root.config(menu=menubar)
root.mainloop()
上述的設(shè)計(jì)理念是menubar=Menu(root)線建立menubar對(duì)象,然后menubar.add_command(label="Hello",command=hello)
和menubar.add_command(label="Exit",command=root.destroy)分別將Hello!和Exit!命令
列表建立在menubar上彬檀。
上述程序雖然可以執(zhí)行帆啃,但這并不是一個(gè)很正規(guī)的菜單設(shè)計(jì)方式,正規(guī)的菜單是在最上方先建立
菜單類(lèi)別窍帝,然后才在各菜單類(lèi)別內(nèi)建立相關(guān)子菜單列表努潘,這些子菜單列表是用下拉式窗體顯示。
樣例2:建立一個(gè)File菜單坤学,然后在此菜單內(nèi)建立下拉式列表命令:
from tkinter import *
from tkinter import messagebox
def newFile():
messagebox.showinfo("New File","新建文檔")
root=Tk()
root.title("ch16_2")
root.geometry("300x180")
menubar=Menu(root)
filemenu=Menu(menubar)
menubar.add_cascade(label="File",menu=filemenu)
filemenu.add_command(label="New File",command=newFile)
filemenu.add_command(label="Exit",command=root.destroy)
root.config(menu=menubar)
root.mainloop()
tearoff參數(shù)
tearoff參數(shù)的默認(rèn)值是1疯坤,至于其他細(xì)節(jié)可以參考該部分的說(shuō)明,由于這是默認(rèn)值深浮,所以若是
開(kāi)啟菜單時(shí)可以看到"tearoff"=1參數(shù)產(chǎn)生的虛線分隔線压怠。
若單擊這個(gè)虛線,可以讓這個(gè)下拉菜單分離飞苇。
樣例:建立菜單時(shí)設(shè)置"tearoff=False"菌瘫,隱藏虛線。
from tkinter import *
from tkinter import messagebox
def newFile():
messagebox.showinfo("New File","新建文檔")
root=Tk()
root.title("ch16_2")
root.geometry("300x180")
menubar=Menu(root)
filemenu=Menu(menubar,tearoff=False)
menubar.add_cascade(label="File",menu=filemenu)
filemenu.add_command(label="New File",command=newFile)
filemenu.add_command(label="Exit",command=root.destroy)
root.config(menu=menubar)
root.mainloop()
菜單列表間加上分隔線
在建立下拉菜單列表時(shí)布卡,如果列表項(xiàng)目有很多雨让,可以適當(dāng)?shù)厥褂胊dd_separator()方法在
菜單列表內(nèi)加上分隔線。
樣例:在File菜單內(nèi)建立5格指令列表忿等,同時(shí)適時(shí)地在指令列表間建立分隔線栖忠。
from tkinter import *
from tkinter import messagebox
def newFile():
messagebox.showinfo("New File","新建文檔")
def openFile():
messagebox.showinfo("New File","打開(kāi)文檔")
def saveFile():
messagebox.showinfo("New File","保存文檔")
def saveAsFile():
messagebox.showinfo("New File","另存為")
root=Tk()
root.title("ch16_4")
root.geometry("300x180")
menubar=Menu(root)
filemenu=Menu(menubar)
menubar.add_cascade(label="File",menu=filemenu)
filemenu.add_command(label="New File",command=openFile)
filemenu.add_command(label="Open File",command=openFile)
filemenu.add_separator()
filemenu.add_command(label="Save",command=saveFile)
filemenu.add_command(label="Save As",command=saveAsFile)
filemenu.add_separator()
filemenu.add_command(label="Exit",command=root.destroy)
root.config(menu=menubar)
root.mainloop()
建立多個(gè)菜單的應(yīng)用
一個(gè)實(shí)用的窗口應(yīng)用程序在最上層menubar中應(yīng)該會(huì)有多組菜單類(lèi)別。
樣例:增加Help菜單贸街,在這個(gè)菜單內(nèi)增加About me命令列表庵寞。
from tkinter import *
from tkinter import messagebox
def newFile():
messagebox.showinfo("New File","新建文檔")
def openFile():
messagebox.showinfo("New File","打開(kāi)文檔")
def saveFile():
messagebox.showinfo("New File","保存文檔")
def saveAsFile():
messagebox.showinfo("New File","另存為")
def aboutMe():
messagebox.showinfo("New File","盧振雄")
root=Tk()
root.title("ch16_4")
root.geometry("300x180")
menubar=Menu(root)
filemenu=Menu(menubar)
menubar.add_cascade(label="File",menu=filemenu)
filemenu.add_command(label="New File",command=openFile)
filemenu.add_command(label="Open File",command=openFile)
filemenu.add_separator()
filemenu.add_command(label="Save",command=saveFile)
filemenu.add_command(label="Save As",command=saveAsFile)
filemenu.add_separator()
filemenu.add_command(label="Exit",command=root.destroy)
helpmenu=Menu(menubar)
menubar.add_cascade(label="Help",menu=helpmenu)
helpmenu.add_command(label="Abount me",command=aboutMe)
root.config(menu=menubar)
root.mainloop()
Alt快捷鍵
快捷鍵是某個(gè)菜單類(lèi)別或是列表指令的英文字符串內(nèi)為單一字母增加下劃線,然后可以用Alt
鍵先啟動(dòng)此功能薛匪,當(dāng)菜單顯示下劃線字母時(shí)捐川,可以直接按執(zhí)行字母鍵啟動(dòng)該功能。設(shè)計(jì)方式是
在下列兩個(gè)方法內(nèi)增加underline參數(shù)蛋辈。
add_cascade(···,underline=n) #n代表第幾個(gè)索引字母含下劃線
add_command(···,underline=n) #代表第幾個(gè)索引字母含下劃線
add_cascade()的underline是為菜單類(lèi)別增加字母下劃線属拾,add_command()的underline是為
命令列表增加字母下劃線将谊,上述索引從0開(kāi)始計(jì)算。當(dāng)然渐白,在將所選擇的字母處理成帶有下畫(huà)線
時(shí)尊浓,必須適度選擇具有代表性的字母,通常會(huì)是字符串的第一個(gè)字母纯衍。例如File菜單可以選擇F栋齿,
Help菜單可以選擇H,等等襟诸。有時(shí)候會(huì)發(fā)生字符串的第一個(gè)字母與先前的字母重復(fù)瓦堵,例如,Save
的S與Save As的S,這時(shí)第二個(gè)出現(xiàn)的字符串可以適當(dāng)選擇其他字母歌亲。
樣例:為菜單類(lèi)別和列表命令建立快捷鍵菇用。
from tkinter import *
from tkinter import messagebox
def newFile():
messagebox.showinfo("New File","新建文檔")
def openFile():
messagebox.showinfo("New File","打開(kāi)文檔")
def saveFile():
messagebox.showinfo("New File","保存文檔")
def saveAsFile():
messagebox.showinfo("New File","另存為")
def aboutMe():
messagebox.showinfo("New File","盧振雄")
root=Tk()
root.title("ch16_6")
root.geometry("300x180")
menubar=Menu(root)
filemenu=Menu(menubar)
menubar.add_cascade(label="File",menu=filemenu,underline=0)
filemenu.add_command(label="New File",command=openFile,underline=0)
filemenu.add_command(label="Open File",command=openFile,underline=0)
filemenu.add_separator()
filemenu.add_command(label="Save",command=saveFile,underline=0)
filemenu.add_command(label="Save As",command=saveAsFile,underline=5)
filemenu.add_separator()
filemenu.add_command(label="Exit",command=root.destroy,underline=0)
helpmenu=Menu(menubar)
menubar.add_cascade(label="Help",menu=helpmenu,underline=0)
helpmenu.add_command(label="Abount me",command=aboutMe,underline=1)
root.config(menu=menubar)
root.mainloop()
首先必須按Alt鍵啟動(dòng)此功能。
Ctrl+快捷鍵
在設(shè)計(jì)菜單列表時(shí)也可以在指令右邊設(shè)計(jì)Ctrl+X之類(lèi)的快捷鍵陷揪,X是代表一個(gè)快捷鍵的英文字母惋鸥,
要設(shè)計(jì)這類(lèi)操作可以借助accelerator參數(shù),然后再使用bind()方法將此快捷鍵綁定一個(gè)callback()
方法悍缠。
樣例:設(shè)計(jì)File菜單的New File子菜單卦绣,可以按Ctrl+N組合鍵。
from tkinter import *
from tkinter import messagebox
def newFile():
messagebox.showinfo("New File","新建文檔")
root=Tk()
root.title("ch16_7")
root.geometry("300x180")
menubar=Menu(root)
filemenu=Menu(menubar)
menubar.add_cascade(label="File",menu=filemenu,underline=0)
filemenu.add_command(label="New File",command=newFile,accelerator="Ctrl+N")
filemenu.add_separator()
filemenu.add_command(label="Exit",command=root.destroy,underline=0)
root.config(menu=menubar)
root.bind("<Control-N>",lambda event:messagebox.showinfo("New File","新建文檔"))
root.mainloop()
由于所綁定事件會(huì)回傳event事件給callback()方法飞蚓,所以無(wú)法直接調(diào)用newFile()方法滤港,因?yàn)閚ewFile()
方法沒(méi)有傳遞任何參數(shù),碰上這種問(wèn)題如果憑直覺(jué)再建立一個(gè)專供此快捷鍵使用的方法趴拧,此例中
使用Lambda表達(dá)式處理溅漾,以簡(jiǎn)化整個(gè)程序的設(shè)計(jì)。
建立子菜單
建立菜單時(shí)所使用的概念如下八堡。
menubar=Menu(root)
filemenu=Menu(menubar)
menu.add_cascade(label=" File",menu=filemenu)
上述是建立File菜單樟凄。所謂的建立子菜單就是在File菜單內(nèi)另外建立一個(gè)子菜單聘芜。如果所要
建立的子菜單是Find子菜單兄渺,所要建的對(duì)象是findmenu,此時(shí)可以使用下列命令汰现。
findmenu=Menu(filemenu)
xxx #這是建立子菜單列表
xxx #這是建立子菜單列表
filemenu.add_cascade(label=" Find",menu=findmenu)
樣例:在File菜單內(nèi)建立Find子菜單挂谍,這個(gè)子菜單內(nèi)有FindNext和Find Pre命令。
from tkinter import *
from tkinter import messagebox
def findNext():
messagebox.showinfo("Find Next","查找下一個(gè)")
def findPre():
messagebox.showinfo("Find Pre","查找下一個(gè)")
root=Tk()
root.title("ch16_8")
root.geometry("300x180")
menubar=Menu(root)
filemenu=Menu(menubar)
menubar.add_cascade(label="File",menu=filemenu,underline=0)
findmenu=Menu(filemenu,tearoff=False)
findmenu.add_command(label="Find Next",command=findNext)
findmenu.add_command(label="Find Pre",command=findPre)
filemenu.add_cascade(label="Find",menu=findmenu)
filemenu.add_separator()
filemenu.add_command(label="Exit",command=root.destroy,underline=0)
root.config(menu=menubar)
root.mainloop()
由于在子菜單的設(shè)計(jì)中一般省略虛線分隔線設(shè)計(jì)瞎饲,所以在Menu()方法中增加了tearoff=False
建立彈出式菜單
當(dāng)使用Windows操作系統(tǒng)時(shí)口叙,可以在桌面上單擊鼠標(biāo)右鍵,此時(shí)會(huì)彈出一個(gè)菜單嗅战,這就是
彈出式菜單Popup menu妄田,有人將此菜單稱為快捷菜單俺亮。
設(shè)計(jì)這類(lèi)菜單與先前需在窗口的menubar區(qū)建立菜單類(lèi)別有一些差異,建立好Menu對(duì)象后疟呐,
可以直接利用此對(duì)象建立指令列表脚曾,最后再單擊鼠標(biāo)右鍵操作綁定顯示彈出菜單即可。
popupmenu=Menu(root,tearoff=False) #隱藏虛線分隔線
popupmenu.add_command(label=" xx",command=" yy" 建立指令列表
···.
root.bind("<Button-3>",callback) #綁定單擊鼠標(biāo)右鍵顯示彈出菜單)
樣例:設(shè)計(jì)彈出菜單启具,這個(gè)彈出菜單中有兩個(gè)子菜單本讥,一個(gè)是Minimize可以將窗口縮成
圖標(biāo),另一個(gè)是Exit結(jié)束程序鲁冯。
from tkinter import *
from tkinter import messagebox
def minimizeIcon():
root.iconify()
def showPopupMenu(event):
popupmenu.post(event.x_root,event.y_root)
root=Tk()
root.title("ch16_9")
root.geometry("300x180")
popupmenu=Menu(root,tearoff=False)
popupmenu.add_command(label="Minimize",command=minimizeIcon)
popupmenu.add_command(label="Exit",command=root.destroy)
root.bind("<Button-3>",showPopupMenu)
root.mainloop()
iconify()是最小化窗口拷沸,post()方法是由popupmenu對(duì)像啟動(dòng),相當(dāng)于可以在鼠標(biāo)
光標(biāo)位置(event.x_root,event.y_root)彈出此菜單薯演。
add_checkbutton()
在設(shè)計(jì)菜單列表時(shí)撞芍,也可以將命令用復(fù)選框(checkbutton)方式表示,也稱為
Check menu button跨扮,下面將用程序?qū)嵗v解勤庐。執(zhí)行時(shí),在窗口下方可以看到
狀態(tài)欄好港,View菜單中的Status其實(shí)就是用的復(fù)選框命令愉镰。
上述工作原理是當(dāng)Status狀態(tài)為T(mén)rue時(shí),Status左邊可以勾選符號(hào)钧汹,同時(shí)窗口下方
會(huì)有狀態(tài)欄丈探。當(dāng)Status狀態(tài)是False時(shí),左邊沒(méi)有勾選符號(hào)拔莱,同時(shí)窗口下方不會(huì)有狀態(tài)欄碗降。
Check menu button的工作原理和Widget對(duì)象Checkbutton相同,單擊可以切換狀態(tài)True
或False塘秦。
樣例:設(shè)計(jì)當(dāng)Status為T(mén)rue時(shí)可以顯示狀態(tài)欄讼渊,當(dāng)Status為False時(shí)可以隱藏狀態(tài)欄,這個(gè)
程序的狀態(tài)欄是用標(biāo)簽Label方式處理尊剔。
from tkinter import *
def status():
if demoStatus.get():
statusLabel.pack(side=BOTTOM,fill=X)
else:
statusLabel.pack_forget()
root=Tk()
root.title("ch16_10")
root.geometry("300x180")
menubar=Menu(root)
filemenu=Menu(menubar,tearoff=False)
menubar.add_cascade(lab="File",menu=filemenu)
filemenu.add_command(label="Exit",command=root.destroy)
viewmenu=Menu(menubar,tearoff=False)
menubar.add_cascade(label="View",menu=viewmenu)
demoStatus=BooleanVar()
demoStatus.set(True)
viewmenu.add_checkbutton(label="Status",command=status,
variable=demoStatus)
root.config(menu=menubar)
statusVar=StringVar()
statusVar.set("顯示")
statusLabel=Label(root,textvariable=statusVar,relief="raised")
statusLabel.pack(side=BOTTOM,fill=X)
root.mainloop()
上述程序的重點(diǎn)如下:在View菜單內(nèi)使用add_checkbutton()創(chuàng)建Check menu button爪幻,
此對(duì)象名稱是Status,同時(shí)使用demoStatus布爾變量記錄目前狀態(tài)是True或False须误,這個(gè)
Status對(duì)象當(dāng)有狀態(tài)改變時(shí)執(zhí)行status()方法挨稿。
status()方法中如果目前demoStatus是True,執(zhí)行statusLabel.pack(side=BOTTOM,fill=X)
包裝顯示窗口的標(biāo)簽狀態(tài)欄京痢,相當(dāng)于顯示statusLabel奶甘。如果目前demoStatus是False,執(zhí)行
statusLabel.pack_forget()祭椰,這個(gè)方法可以隱藏狀態(tài)標(biāo)簽欄臭家。
建立工具欄Toolbar
在窗口程序設(shè)計(jì)中疲陕,另一個(gè)很重要的概念是將常用的命令組成工具欄,放在窗口內(nèi)以方便用戶
隨時(shí)調(diào)用钉赁。tkinter模塊沒(méi)有提供Toolbar模塊鸭轮,不過(guò)我們可以使用Frame建立工具欄。
樣例:這個(gè)程序會(huì)建立一個(gè)File菜單橄霉,菜單內(nèi)有Exit命令窃爷。這個(gè)程序也建立一個(gè)工具欄,在工具欄
內(nèi)有exitBtn按鈕姓蜂。這個(gè)程序不論是執(zhí)行File菜單的Exit命令或是單擊工具欄中的exitBtn按鈕按厘,都
可以讓程序結(jié)束。
from tkinter import *
root=Tk()
root.title("ch16_10")
root.geometry("300x180")
menubar=Menu(root)
filemenu=Menu(menubar,tearoff=False)
menubar.add_cascade(lab="File",menu=filemenu)
filemenu.add_command(label="Exit",command=root.destroy)
toolbar=Frame(root,relief=RAISED,borderwidth=3)
sunGif=PhotoImage(file="sun.gif")
exitBtn=Button(toolbar,image=sunGif,command=root.destroy)
exitBtn.pack(side=LEFT,padx=3,pady=3)
toolbar.pack(side=TOP,fill=X)
root.config(menu=menubar)
root.mainloop()