tkinter中,菜單控件組織方法有兩種,使用中常出現混淆,為明晰各個正確用法,特整理撰寫此博文。菜單控件的組織實際上是通過一個“母菜單”和“子菜單”構成,“母菜單”一方面與master連接(即與依附控件的關聯),一方面與”子菜單“連接,而子菜單則負責展示及響應。
”母菜單“可以采用Menu類或者Menubutton類,由此產生出兩種組織方法:
(1)Menu類:
能與Toplevel和TK類關聯,但不可以與Frame類關聯:menu=Menu(Toplevel());Toplevel().config(menu=menu)
與”子菜單“的關聯為:pulldown=Menu(menu);menu.add_cascade(menu=pulldown,label='text')
而不能與Tk類,和Frame類關聯;
如下代碼:
>>> from tkinter import *
>>> root=Tk()
>>> menu1=Menu(root)
>>> root.config(menu=menu1,label='test1')
Traceback (most recent call last):
File "<pyshell#3>", line 1, in <module>
root.config(menu=menu1,label='test1')
File "C:\Users\旺仔QQ糖\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 1485, in configure
return self._configure('configure', cnf, kw)
File "C:\Users\旺仔QQ糖\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 1476, in _configure
self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: unknown option "-label"
>>> root.config(menu=menu1)
>>> pulldown=Menu(menu1)
>>> pulldown.add_command(label='test2')
>>> menu1.add_cascade(menu=pulldown,label='testit')
>>> frm=Frame(root)
>>> frm.pack(side=BOTTOM)
>>> menu2=Menu(frm)
>>> frm.config(menu=menu2,label='test3')
Traceback (most recent call last):
File "<pyshell#11>", line 1, in <module>
frm.config(menu=menu2,label='test3')
File "C:\Users\旺仔QQ糖\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 1485, in configure
return self._configure('configure', cnf, kw)
File "C:\Users\旺仔QQ糖\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 1476, in _configure
self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: unknown option "-menu"
>>> tplv=Toplevel(root)
>>> menu3=Menu(tplv)
>>> tplv.config(menu=menu3,label='test3')
Traceback (most recent call last):
File "<pyshell#14>", line 1, in <module>
tplv.config(menu=menu3,label='test3')
File "C:\Users\旺仔QQ糖\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 1485, in configure
return self._configure('configure', cnf, kw)
File "C:\Users\旺仔QQ糖\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 1476, in _configure
self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: unknown option "-label"
>>> tplv.config(menu=menu3)
>>> menuu=Menu(menu3)
>>> menuu.add_command(label='try it...')
>>> menu3.add_cascade(menu=menuu,label='getit')

(2)Menubutton類:
可以與Tk類,Frame類,Toplevel類關聯:menubutton=Menubutton(Root,text='text');menubutton.pack();
與”子菜單“的關聯為:pulldown=Menu(menubutton);menubutton.config(menu=pulldown)
>>> menbt=Menubutton(root,text='help1')
>>> menbt.pack()
>>> menbt.add_command(label='1')
Traceback (most recent call last):
File "<pyshell#23>", line 1, in <module>
menbt.add_command(label='1')
AttributeError: 'Menubutton' object has no attribute 'add_command'
>>> frm=Frame(root)
>>> frm.pack(side=BOTTOM)
>>> Menubutton(frm,text='test1')
<tkinter.Menubutton object .!frame.!menubutton>
>>> Menubutton(frm,text='test1').pack()
>>> tplv1=Toplevel(root)
>>> Menubutton(tplv1,text='test2')
<tkinter.Menubutton object .!toplevel.!menubutton>
>>> Menubutton(tplv1,text='test2').pack()

而當”子菜單“擴展時,可以繼續使用add_cascade方法,從這個角度看,”母菜單“使用Menu類的組織方法可以看作是Menu控件的擴展方法。
下面是兩個簡單的Demo:
>>> from tkinter import * >>> root=Toplevel() >>> menu=Menu(root) >>> root.config(menu=menu) >>> pulldow=Menu(menu) >>> pulldow.add_command(label='test1') >>> pulldow.add_command(label='test2') >>> pulldow.add_separator() >>> menu.add_cascade(menu=pulldow,label='menu')
>>> from tkinter import * >>> root=Tk() >>> menubtn=Menubutton(root,text='menubtn') >>> menubtn.pack() >>> pulldown=Menu(menubtn) >>> pulldown.add_command(label='test1',command=None) >>> pulldown.add_command(label='test2',command=None) >>> menubtn.config(menu=pulldown)
總結:兩種方式中,第一個Menu的安置需要依附控件(root,toplevel)的config方法;”母菜單“為Menu類時,實質是Menu的擴展;”母菜單“為Menubutton時,它本身具有Button的屬性,所以參數需要master,text,command,聯結”子菜單“時(肯定是第一個Menu類),所以需要config方法,需要注意的是Menu不可以依附在Frame上,而Menubutton可以。
