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可以。