Tkinter 提供了一个组件 Menu 用来实现顶级菜单,下拉菜单和弹出菜单。
目录
创建一个顶级菜单
实现下拉菜单和级联菜单:
实现弹出菜单
选择菜单
星号* 作用
一、星号(*)作为形参,表示调用可变参数函数:
二、星号(*)作为实参时,表示通过解包参数调用函数
from tkinter import *
root = Tk()
def callback():
print("你好")
menubar = Menu(root)
menubar.add_command(label='Hello', command=callback)
menubar.add_command(label='quit', command=root.quit)
root.config(menu=menubar) #虽然menu已经创建,但是还没添加到root窗口中,所以要调用config方法对root的menu选项相关联
#在IDLE中点退出没反应是因为IDLE也是Tkinter实现的,他们两个共用了一个mainloop(),退出代码重复了,产生了冲突
mainloop()
from tkinter import *
root = Tk()
def callback():
print("你好")
menubar = Menu(root)
filemenu = Menu(menubar, tearoff=False)
filemenu.add_command(label='打开', command=callback)
filemenu.add_command(label='保存', command=callback)
filemenu.add_separator() #添加分割线
filemenu.add_command(label='退出', command=root.quit)
menubar.add_cascade(label='文件', menu=filemenu) #创建级联菜单,menu选项指定下一级的菜单是什么
editmenu = Menu(menubar, tearoff=False)
editmenu.add_command(label='剪切', command=callback)
editmenu.add_command(label='拷贝', command=callback)
editmenu.add_separator() #添加分割线
editmenu.add_command(label='粘贴', command=callback)
menubar.add_cascade(label='编辑', menu=editmenu)
root.config(menu=menubar)
#在IDLE中点退出没反应是因为IDLE也是Tkinter实现的,他们两个共用了一个mainloop(),退出代码重复了,产生了冲突
mainloop()
from tkinter import *
root = Tk()
def callback():
print("你好")
menubar = Menu(root)
menubar.add_command(label='撤销', command=callback)
menubar.add_command(label='重做', command=callback)
frame = Frame(root, width=512, height=512)
frame.pack()
def popup(event):
menubar.post(event.x_root, event.y_root)
frame.bind("", popup)
mainloop()
点击右键出现如下菜单:
from tkinter import *
root = Tk()
def callback():
print("你好")
menubar = Menu(root)
openVar = IntVar()
saveVar = IntVar()
quitVar = IntVar()
filemenu = Menu(menubar, tearoff=False)
filemenu.add_checkbutton(label='打开', command=callback, variable=openVar)
filemenu.add_checkbutton(label='保存', command=callback, variable=saveVar)
filemenu.add_checkbutton() #添加分割线
filemenu.add_checkbutton(label='退出', command=root.quit, variable=quitVar)
menubar.add_cascade(label='文件', menu=filemenu)
editVar = IntVar()
editmenu = Menu(menubar, tearoff=False)
editmenu.add_radiobutton(label='剪切', command=callback, variable=editVar, value=1)
editmenu.add_radiobutton(label='拷贝', command=callback, variable=editVar, value=2)
editmenu.add_separator() #添加分割线
editmenu.add_radiobutton(label='粘贴', command=callback, variable=editVar, value=3)
menubar.add_cascade(label='编辑', menu=editmenu)
root.config(menu=menubar)
#在IDLE中点退出没反应是因为IDLE也是Tkinter实现的,他们两个共用了一个mainloop(),退出代码重复了,产生了冲突
mainloop()
Menubutton 组件是一个和 Menu 组件相关联的按钮,事实上就是 Menu+Button。它可以在窗口的任何位置放一个 Button,点开后是一个 Menu。由于一开始并没有顶级菜单,所以用 Menubutton 实现一个个按钮在最上面,点开一个出来一个 Menu。不过现在 Tkinter 出现了顶级菜单,Menubutton 就没什么用处了。
from tkinter import *
root = Tk()
def callback():
print("你好")
mb = Menubutton(root, text='点我', relief=RAISED) #relief设计按钮的样式
mb.pack()
filemenu = Menu(mb, tearoff=False)
filemenu.add_command(label='打开', command=callback)
filemenu.add_command(label='保存', command=callback)
filemenu.add_command() #添加分割线
filemenu.add_command(label='退出', command=root.quit)
mb.config(menu=filemenu)
mainloop()
OptionMenu(选择菜单)组件。其实,Optionmenu 就是下拉菜单的一个改版,但是他的发明弥补了 Listbox(列表框)无法实现下拉列表框的遗憾,因为创建一个选择菜单的效果和创建下拉列表框的效果是一样的。
创建一个选择菜单非常简单,只需要给它一个 Tkinter 变量(用于记录用户选择了什么)以及若干选项即可:
from tkinter import *
root = Tk()
variable = StringVar()
variable.set('one') #设置默认选中one选项
#可以用该Tkinter变量的get方法获得用户点击的内容
w = OptionMenu(root, variable, 'one', 'two', 'three') #关联一个Tkinter的变量variable,表示用户选中了哪个值
#'one', 'two', 'three'表示的是选择菜单有哪些选项
w.pack()
mainloop()
下面将演示如何将很多项添加到选择菜单中,就是当很多选项在元组或者列表中时,如何把他们添加到选择菜单中。
from tkinter import *
OPTIONS = [
'1',
'asf',
'hdfs',
'safsdv'
]
root = Tk()
variable = StringVar()
variable.set('OPTIONS[0]')
w = OptionMenu(root, variable, *OPTIONS) #不加*整个列表会被作为一个选项
w.pack()
mainloop()
注意:星号(*)作为形参的时候是起到“打包”的作用,相反,作为实参的时候是起到“解包”的作用
通过在形参前加一个星号(*)或两个星号(**)来指定函数可以接受任意数量的参数:
>>> def fun1(*args):
print(type(args))
print(args)
>>> fun1(1, 2, 3, 4)
(1, 2, 3, 4)
>>> def fun2(**args):
print(type(args))
print(args)
>>> fun2(a=1, b=2, c=3, d=4)
{'a': 1, 'b': 2, 'c': 3, 'd': 4}
从两个示例可以看出:当参数形如 *args 时,传递给函数的任意个实参惠安为止打包成一个元组(tuple);当参数形如 **args 时,传递给函数的任意个 key=value 实参会被包装进一个字典(dict)。
有打包就有解包,通过在实参前加一个星号(*)或两个星号(**)来对列表(list)、元组(tuple)或字典(dict)进行解包。
>>> def fun1(*args):
print(type(args))
print(args)
>>> a = [1, 2, 3, 4]
>>> b = (1, 2, 3, 4)
>>> fun1(*a)
(1, 2, 3, 4)
>>> fun1(*b)
(1, 2, 3, 4)
>>> def fun2(**args):
print(type(args))
print(args)
>>> c = {'one':1, 'two':2, 'three':3}
>>> fun2(**c)
{'one': 1, 'two': 2, 'three': 3}
总结:一个星号(*)用来打包和解包序列,两个星号(**)用来打包和解包字典。