汕头网站制作推荐wordpress文章出现404
我们不难发现,几乎每一个应用程序都有一些相同的地方,比如说:标题栏、状态栏、边框、滚动条、工作区。还有的就是 菜单。
传统的菜单有大家熟悉的 File,Edit,Help等,点开之后,是下拉菜单,今天我们就来学习使用 tkinter 如何制作这样子的菜单。tkinter 提供了一个叫做 Menu 的组件,主要是用于实现顶级菜单、下拉菜单和弹出菜单。
由于该组件是由底层代码来实现的,并且已经优化好了,我们这里不建议你自行通过按钮或者其他的组件来实现菜单的功能,我知道你可以。但是Python的开发原则就是有得用,你就别自己瞎搞。我说的是正式开发中,在学习中,没事搞一搞是可以让我们学习到更多知识的。
我们先来实现创建一个顶级菜单:
-  
import tkinter as tk -  
root = tk.Tk() -  
def callback(): -  
print("你好~") -  
menubar = tk.Menu(root) -  
menubar.add_command(label = "hello", command = callback) -  
menubar.add_command(label = "quit", command = root.quit) -  
root.config(menu = menubar)#把创建的 menubar 与根窗口的 menu 绑定,才会显示菜单 -  
root.mainloop() 

我们接下来实现下拉菜单,我们要实现下拉菜单,例如我们点一下 hello,它会出来很多其他的选项,而不是执行一个命令,方法也是大同小异的,只是说下拉菜单我们把它们添加到主菜单上,而不是窗口上,我们举例说明:
-  
import tkinter as tk -  
root = tk.Tk() -  
def callback(): -  
print("你好~") -  
menubar = tk.Menu(root) -  
###创建文件菜单 -  
filemenu = tk.Menu(menubar) -  
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) -  
###创建编辑菜单 -  
editmenu = tk.Menu(menubar, tearoff = False) #tearoff = False ,就是没有下拉菜单顶部的虚线 -  
editmenu.add_command(label = "剪切", command = callback) -  
editmenu.add_command(label = "拷贝", command = callback) -  
editmenu.add_command(label = "粘贴", command = root.quit) -  
#创建级联菜单 -  
menubar.add_cascade(label = "编辑", menu = editmenu) -  
root.config(menu = menubar)#把创建的 menubar 与根窗口的 menu 绑定,才会显示菜单 -  
root.mainloop() 


我们来说一下 tearoff 的作用,tearoff 默认为 True,显性特点就是有一点虚线,当我们点击这一条虚线时:(菜单可以被撕下(tearoff))

我们再来说一个弹出菜单:
-  
import tkinter as tk -  
root = tk.Tk() -  
def callback(): -  
print("你好~") -  
menubar = tk.Menu(root) -  
menubar = tk.Menu(menubar) -  
menubar.add_command(label = "撤销", command = callback) -  
menubar.add_command(label = "退出", command = root.quit) -  
frame = tk.Frame(root, width =512, height = 512) -  
frame.pack() -  
def popup(event): -  
menubar.post(event.x_root, event.y_root) -  
frame.bind("<Button-3>", popup) #<Button-3>就是鼠标右键 -  
root.mainloop() 
运行后,点击鼠标右键:

菜单不仅可以添加我们普通的命令行(add_command),事实上我们还可以添加 像 Checkbutton(多选按钮)和 Radiobutton(单选按钮)这样子的菜单项,它们的用法就和 Checkbutton 和 Radiobutton 组件是差不多的。
我们继续创建一个带有 checkbutton 和 radiobutton 的菜单给大家看看:
-  
import tkinter as tk -  
root = tk.Tk() -  
def callback(): -  
print("你好~") -  
menubar = tk.Menu(root) -  
openVar = tk.IntVar() -  
saveVar = tk.IntVar() -  
quitVar = tk.IntVar() -  
filemenu = tk.Menu(menubar, tearoff = False) -  
filemenu.add_checkbutton(label = "打开", command = callback, variable = openVar) -  
filemenu.add_checkbutton(label = "保存", command = callback, variable = saveVar) -  
filemenu.add_separator() -  
filemenu.add_checkbutton(label = "退出", command = root.quit, variable = quitVar) -  
menubar.add_cascade(label = "文件", menu = filemenu) -  
editVar = tk.IntVar() -  
editmenu = tk.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_radiobutton(label = "粘贴", command = root.quit, variable = editVar, value = 3) -  
menubar.add_cascade(label = "编辑", menu = editmenu) -  
root.config(menu = menubar) -  
root.mainloop() 
我们接下来介绍一个新的组件 Menubutton。
Menubutton 组件是一个与Menu 组件 相关联的按钮,(事实上就是Menu + Button),它可以放在窗口中的任意位置,并且在被按下时弹出下拉菜单。
这个组件是有一些历史意义的,因为刚开始是没有顶级菜单的,那么就用 Menubutton 实现一个个按钮在上面,点一个按钮就出现菜单。
现在该组件适用于你希望菜单按钮出现在其他位置的时候。
举个例子:
-  
import tkinter as tk -  
root = tk.Tk() -  
def callback(): -  
print("你好~") -  
mb = tk.Menubutton(root, text = "点我", relief = "raised") -  
mb.pack() -  
filemenu = tk.Menu(mb, tearoff = False) -  
filemenu.add_command(label = "打开", command = callback) -  
filemenu.add_command(label = "保存", command = callback) -  
filemenu.add_separator() -  
filemenu.add_command(label = "退出", command = root.quit) -  
mb.config(menu = filemenu) -  
root.mainloop() 

我们接下来 介绍一下 Optionmenu(选择菜单)。
OptionMenu(选择菜单)事实上是下拉菜单的改版,它的发明弥补了Listbox 组件无法实现下拉列表框的遗憾。因为事实上创建一个选择菜单,就跟一个下拉列表框是一个道理的。我们来看一下它实现的效果就知道了。
-  
import tkinter as tk -  
root = tk.Tk() -  
variable = tk.StringVar() -  
variable.set("one") -  
w = tk.OptionMenu(root, variable, "one", "two", "three") -  
w.pack() -  
root.mainloop() 

最后,演示一下,如何将很多项添加到选择菜单中,就是很多选项在一个列表或者元组中,如何将他们添加到 OptionMenu 菜单中,
-  
import tkinter as tk -  
OPTIONS = [ -  
"Wuhan", -  
"Beijing", -  
"Shanghai", -  
"Tianjin", -  
"Aomen", -  
"Xianggang", -  
"Hankou" -  
] -  
root = tk.Tk() -  
variable = tk.StringVar() -  
variable.set(OPTIONS[0]) -  
w = tk.OptionMenu(root, variable, *OPTIONS) #*号有一个解包的功能,如果没有 * 号,就把整个列表当做一个选项了 -  
w.pack() -  
root.mainloop() 

注意:星号(*)作为形参的时候是起到“打包”的作用,相反,作为实参的时候是起到“解包”的作用。
一、星号(*)作为形参,表示调用可变参数函数:
 通过在形参前加一个星号(*)或两个星号(**)来指定函数可以接收任意数量的实参。
-  
def fun1(*args): -  
print(type(args)) -  
print(args) -  
 -  
fun1(1, 2, 3, 4, 5) -  
# 输出: -  
# <class 'tuple'> -  
# (1, 2, 3, 4, 5) 
-  
def fun2(**args): -  
print(type(args)) -  
print(args) -  
 -  
fun2(a=1, b=2, c=3, d=4, e=5) -  
# 输出: -  
# <class 'dict'> -  
# {'e': 5, 'a': 1, 'c': 3, 'd': 4, 'b': 2} 
- 从两个示例的输出可以看出:当参数形如 *args 时,传递给函数的任意个实参会按位置打包成一个元组(tuple);
 - 当参数形如 **args 时,传递给函数的任意个 key = value 实参会被包装进一个字典(dict)。
 
二、星号(*)作为实参时,表示通过解包参数调用函数
 有打包就有解包,通过在实参前加一个星号(*)或两个星号(**)来对列表(list)、元组(tuple)或字典(dict)进行解包:
-  
>>> a = [1, 2, 3, 4, 5] -  
>>> b = (1, 2, 3, 4, 5) -  
>>> fun1(*a) -  
(1, 2, 3, 4, 5) -  
>>> fun1(*b) -  
(1, 2, 3, 4, 5) -  
>>> c = {'one':1, 'two':2, 'three':3} -  
>>> fun2(**c) -  
{'two': 2, 'one': 1, 'three': 3} -  
>>> 
总结:一个星号(*)用来打包和解包序列,两个星号(**)用来打包和解包字典。
