一、说明
本文专门记录如何添加Tkinter的菜单,包括,菜单如何生成,菜单如何布局,菜单如何绑定回调函数,并安排代码示例,凡期望做菜单界面的读者,可以全面参考。
二、创建菜单实现步骤
2.1 总体规划模式
菜单对象与其它Widget一样,需要create(parent)模式生成。但menu本身是个List框架,因此,可以安装嵌入下属menu,因此,通过list的嵌套,构成矩阵式菜单。
2.2 程序实现添加顶层菜单
1.Menu和其他的控件一样,第一个是父类,这里通常可以为窗口(父容器可为根窗体或其他容器控件实例)。有;两个必要步骤:
- 创建菜单,指定根控件。
- 在根配置此菜单
from tkinter import *
root = Tk() # 设置主窗体
root.title('创建菜单概要') # 设置窗体的名称
root.geometry('666x333') # 设置窗体的大小
menutop = Menu(root) # 父容器(top)为根窗体的实例
root.config(menu=menutop) # 如果确实此句,则不会显示菜单分组
root.mainloop()
2.3 程序向顶层菜单添加菜单项目
我们可以利用add_command方法来为它添加菜单项,该菜单位于顶层,添加的菜单项依次向右添加:
menutop.add_command(label='文件')
menutop.add_command(label='操作')
menutop.add_command(label='帮助')
from tkinter import *
root = Tk() # 设置主窗体
root.title('创建菜单概要') # 设置窗体的名称
root.geometry('666x333') # 设置窗体的大小
menutop = Menu(root) # 父容器(top)为根窗体的实例
menutop.add_command(label='文件')
menutop.add_command(label='操作')
menutop.add_command(label='帮助')
root.config(menu=menutop) # 如果确实此句,则不会显示菜单分组
root.mainloop()
效果如图所示,添加的菜单项在顶层依次向右添加
2.4 追加菜单的功能
菜单的实际布局:
- 每个root菜单实际是一个list,对应插入N个对象
- 每个下级菜单实际是一个list,对应插入M个对象
- 将root菜单的list存放下级菜单对象,构成菜单的 NxM 矩阵阵列,如下图.
from tkinter import *
def test():
print("OK!")
root = Tk() # 设置主窗体
root.title('创建菜单概要') # 设置窗体的名称
root.geometry('666x333') # 设置窗体的大小
menutop = Menu(root) # 父容器(top)为根窗体的实例
menuFile = Menu(menutop) # 建立一个下拉菜单menuFile
menutop.add_cascade(label="文件", menu=menuFile)
menuFile.add_command(label="打开", command=test(), accelerator='Ctrl+N')
menuFile.add_command(label="保存", command=test(), accelerator='Ctrl+S')
menuFile.add_separator() # 分割线
menuFile.add_command(label="退出", command=root.destroy, accelerator='Ctrl+Alt')
menuOppe = Menu(menutop) # 建立一个下拉菜单menuFile
menutop.add_cascade(label="编辑", menu=menuOppe)
menuOppe.add_command(label="插入", command=test(), accelerator='Ctrl+N')
menuOppe.add_command(label="删除", command=test(), accelerator='Ctrl+S')
menuOppe.add_separator() # 分割线
menuOppe.add_command(label="撤销", command=root.destroy, accelerator='Ctrl+Alt')
root.config(menu=menutop) # 如果确实此句,则不会显示菜单分组
root.mainloop()
执行以上代码,会出现如下状况:
我们发现,进入程序后,菜单命令被自动执行了!!
三、菜单响应函数add_command
注意:在menu菜单参数command=<想要调用的函数>中,需要在函数名前加上lambda:
- 如果不写lambda的话,command调用的函数总是会自动执行。
- 如果操作函数有参数,也需要lambda函数传递。
示例:
from tkinter import *
def test():
print("OK!")
root = Tk() # 设置主窗体
root.title('创建菜单概要') # 设置窗体的名称
root.geometry('666x333') # 设置窗体的大小
menutop = Menu(root) # 父容器(top)为根窗体的实例
menuFile = Menu(menutop) # 建立一个下拉菜单menuFile
menutop.add_cascade(label="文件", menu=menuFile)
menuFile.add_command(label="打开", command=lambda : test(), accelerator='Ctrl+N')
menuFile.add_command(label="保存", command=lambda :test(), accelerator='Ctrl+S')
menuFile.add_separator() # 分割线
menuFile.add_command(label="退出", command=root.destroy, accelerator='Ctrl+Alt')
menuOppe = Menu(menutop) # 建立一个下拉菜单menuFile
menutop.add_cascade(label="编辑", menu=menuOppe)
menuOppe.add_command(label="插入", command=lambda :test(), accelerator='Ctrl+N')
menuOppe.add_command(label="删除", command=lambda :test(), accelerator='Ctrl+S')
menuOppe.add_separator() # 分割线
menuOppe.add_command(label="撤销", command=root.destroy, accelerator='Ctrl+Alt')
root.config(menu=menutop) # 如果确实此句,则不会显示菜单分组
root.mainloop()
这里修改了回调函数触发方式,以上缺点已经消除。
四、按钮菜单
4.1 关于菜单托盘Menubutton
除了上述,将菜单部署到main窗口顶端,另一种菜单托盘可以将菜单部署到屏幕的其它位置。这是一个独特的菜单方式,是通过Menubutton做为菜单容器,生成类同于按钮的菜单项,与label、button一样停靠于窗口。
4.2 托盘菜单程序实现
from tkinter import *
root = Tk()
root.title("Profile Entry using Grid")
root.geometry("500x300") # set starting size of window
root.maxsize(500, 300) # width x height
root.config(bg="lightgrey")
# Profile picture
image = PhotoImage(file="grayqoon.png")
small_img = image.subsample(4,4)
img = Label(root, image=small_img)
img.grid(row=0, column=0, rowspan=6, padx=5, pady=5)
# Enter specific information for your profile into the following widgets
enter_info = Label(root, text="Please enter your information: ", bg="lightgrey")
enter_info.grid(row=0, column=1, columnspan=4, padx=5, pady=5)
# Name label and entry widgets
Label(root, text="Name", bg="lightgrey").grid(row=1, column=1, padx=5, pady=5, sticky=E)
name = Entry(root, bd=3)
name.grid(row=1, column=2, padx=5, pady=5)
# Gender label and dropdown widgets
gender = Menubutton(root, text="Gender")
gender.grid(row=2, column=2, padx=5, pady=5, sticky=W)
gender.menu = Menu(gender, tearoff=0)
gender["menu"] = gender.menu
# choices in gender dropdown menu
gender.menu.add_cascade(label="Male")
gender.menu.add_cascade(label="Female")
gender.menu.add_cascade(label="Other")
gender.grid()
# Eyecolor label and entry widgets
Label(root, text="Eye Color", bg="lightgrey").grid(row=3, column=1, padx=5, pady=5, sticky=E)
eyes = Entry(root, bd=3)
eyes.grid(row=3, column=2, padx=5, pady=5)
# Height and Weight labels and entry widgets
Label(root, text="Height", bg="lightgrey").grid(row=4, column=1, padx=5, pady=5, sticky=E)
Label(root, text="inches", bg="lightgrey").grid(row=4, column=3, sticky=W)
height = Entry(root, bd=3)
height.grid(row=4, column=2, padx=5, pady=5)
Label(root, text="Weight", bg="lightgrey").grid(row=5, column=1, padx=5, pady=5, sticky=E)
Label(root, text="lbs", bg="lightgrey").grid(row=5, column=3, sticky=W)
weight = Entry(root, bd=3)
weight.grid(row=5, column=2, padx=5, pady=5)
root.mainloop()