Tkinter库的学习记录16-菜单Menu和工具栏Toolbars

发布时间:2026/7/11 20:14:22
Tkinter库的学习记录16-菜单Menu和工具栏Toolbars 16、菜单Menu和工具栏Toolbars16-1 菜单Menu设计的基本概念窗口中一般会由菜单设计菜单是一种下拉式窗体在这种窗体中可以设计菜单列表建立菜单的方法是Menu()它的语法格式如下。Menu(父对象, options, ...)参数一同上options参数(1) activebackground当光标移至此菜单列表上时的背景颜色。(2) activeborderwidth当被鼠标选取时它的外边框厚度默认是1.(3) activeforeground当光标移至此菜单列表上时的前景色彩。(4) bd所有菜单列表的外边框厚度默认是1(5) bg菜单列表未被选取时的背景色彩。(6) cursor当菜单分离时鼠标光标在列表上的外观。(7) disabledforeground菜单列表是DISABLED时的颜色。(8) font菜单列表文字的字形(9) fg菜单列表未被选取时的前景色彩。(10) image菜单的图标。(11) tearoff菜单上方的分隔线这是一个虚线线条有分隔线时tearoff为True或1此时菜单列表从位置1开始放置同时可以让菜单分离分离方式是开启菜单后单击分隔线。如果将tearoff设为False或0时此时不会显示分隔线也就是菜单无法分离但是菜单列表将从位置0开始存放。相关实例可以参考16-2节。下列是其它相关的方法。(1) add_cascade()建立分层菜单同时让此子功能列表与父菜单建立链接。(2) add_command()增加菜单列表。(3) add_separator()增加菜单列表的分隔线可以参考16-3节。下面程序实例ch16_1建立最上层的菜单列表单击Hello!会出现“欢迎使用菜单”的对话框单击“Exit!”则程序结束。from tkinter import * from tkinter import messagebox def hello(): messagebox.showinfo(Hello, 欢迎使用菜单) root Tk() root.title(ch16_1) root.geometry(300x100) # 建立最上层菜单 menubar Menu(root) menubar.add_command(labelHello!, commandhello) menubar.add_command(labelExit!, commandroot.destroy) root.config(menumenubar) # 显示菜单对象 root.mainloop()执行结果上述的设计理念是第12行先建立menubar对象然后第13、14行分别将Hello!和Exit!命令列表建立在menubar上。上述程序虽然可以执行但这并不是一个正规的菜单设计方式正规菜单是在最上方先建立菜单类别然后才在各菜单类别内建立相关子菜单列表这些子菜单列表适用下拉式窗体显示。程序实例ch16_2建立一个File菜单然后在此菜单内建立下拉式列表命令。from tkinter import * from tkinter import messagebox def newFile(): messagebox.showinfo(New File, 开新档案) root Tk() root.title(ch16_2) root.geometry(300x100) # 建立最上层菜单 menubar Menu(root) # 建立菜单类别对象并将此菜单类别命名为File filemenu Menu(menubar) menubar.add_cascade(labelFile, menufilemenu) # 在file菜单内建立菜单列表 filemenu.add_command(labelNewFile, commandnewFile) filemenu.add_command(labelExit!, commandroot.destroy) root.config(menumenubar) # 显示菜单对象 root.mainloop()执行结果上述建立File菜单的关键是14、15行filemenu则是File菜单的对象第17、18行是使用filemenu对象在FIle菜单内建立New FIle和Exit!命令列表。16-2 tearoff参数在16-1节的Menu()方法的参数options中介绍了tearoff参数它的默认值是1至于其它细节可以参考该部分的说明由于这是默认值所以若是开启菜单时可以看到“tearoff1”参数产生的虚线分隔线。若单击虚线可以让这个下拉菜单分离结果如上方右图所示。下面程序实例ch16_3在第14行建立菜单时设置“tearoffFalse”重新设计ch16_2然后观察执行结果可以发现此虚线已被取消这也造成无法将此下拉菜单从ch16_3的窗口中分离。from tkinter import * from tkinter import messagebox def newFile(): messagebox.showinfo(New File, 开新档案) root Tk() root.title(ch16_3) root.geometry(300x100) # 建立最上层菜单 menubar Menu(root) # 建立菜单类别对象并将此菜单类别命名为File filemenu Menu(menubar, tearoffFalse) menubar.add_cascade(labelFile, menufilemenu) # 在file菜单内建立菜单列表 filemenu.add_command(labelNewFile, commandnewFile) filemenu.add_command(labelExit!, commandroot.destroy) root.config(menumenubar) # 显示菜单对象 root.mainloop()执行结果 参考下图虚线被隐藏了。16-3 菜单列表间加上分隔线在建立下拉菜单列表时如果列表项目有很多可以适当地使用add_separator()方法在菜单列表内加上分隔线。下面程序实例ch16_4扩充设计ch16_2在File菜单内建立5个指令列表同时适时地在指令列表间建立分隔线可以参考第24行和27行。from tkinter import * from tkinter import messagebox def newFile(): messagebox.showinfo(New File, 新建文档) def openFile(): messagebox.showinfo(New File, 打开文档) def saveFile(): messagebox.showinfo(New File, 保存文档) def saveAsFile(): messagebox.showinfo(New File, 另存为) root Tk() root.title(ch16_4) root.geometry(300x180) menubar Menu(root) # 建立最上层菜单 # 建立菜单类别对象并将此菜单类别命名为File filemenu Menu(menubar, tearoffFalse) menubar.add_cascade(labelFile, menufilemenu) # 在file菜单内建立菜单列表 filemenu.add_command(labelNew File, commandnewFile) filemenu.add_command(labelOpen File, commandopenFile) filemenu.add_separator() filemenu.add_command(labelSave, commandsaveFile) filemenu.add_command(labelSave As, commandsaveAsFile) filemenu.add_separator() filemenu.add_command(labelExit!, commandroot.destroy) root.config(menumenubar) # 显示菜单对象 root.mainloop()执行结果16-4 建立多个菜单地应用一个实用地窗口应用程序在最上层menubar中应该会有多组菜单类别在先前地实例中只建立了File菜单filemenu对象所使用的方法如下。menubar Menu(root) filemenu Menu(menubar) menu.add_cascade(labelFile, menufilemenu)如果想要建立多组菜单类别所需要的就是增加设计上述第2、3行然后用不同的名称取代即可。下面程序实例ch16_5扩充实例ch16_4增加Help菜单在这个菜单内增加About me命令列表。from tkinter import * from tkinter import messagebox def newFile(): messagebox.showinfo(New File, 新建文档) def openFile(): messagebox.showinfo(New File, 打开文档) def saveFile(): messagebox.showinfo(New File, 保存文档) def saveAsFile(): messagebox.showinfo(New File, 另存为) def aboutMe(): messagebox.showinfo(Help File, 关于我) root Tk() root.title(ch16_5) root.geometry(300x180) menubar Menu(root) # 建立最上层菜单 # 建立菜单类别对象并将此菜单类别命名为File filemenu Menu(menubar) menubar.add_cascade(labelFile, menufilemenu) # 在file菜单内建立菜单列表 filemenu.add_command(labelNew File, commandnewFile) filemenu.add_command(labelOpen File, commandopenFile) filemenu.add_separator() filemenu.add_command(labelSave, commandsaveFile) filemenu.add_command(labelSave As, commandsaveAsFile) filemenu.add_separator() filemenu.add_command(labelExit!, commandroot.destroy) # 建立菜单类别对象并将此菜单类别命名为Help helpmenu Menu(menubar) menubar.add_cascade(labelHelp, menuhelpmenu) # 在help菜单内建立菜单列表 helpmenu.add_command(labelAbout me, commandaboutMe) root.config(menumenubar) # 显示菜单对象 root.mainloop()执行结果16-5 Alt快捷键快捷键是某个菜单类别或是列表指令的英文字符串内为单一字母增加下划线然后可以用Alt键先启动此功能当菜单显示下划线字母时可以直接按指定字母键启动该功能。设计方式是在下列两个方法内增加underline参数。add_cascade(..., underlinen) # n代表第n个索引字母含下划线 add_cascade(..., underlinen) # n代表第n个索引字母含下划线add_cascade()的underline是为菜单类别增加字母下划线add_command()的underline是为命令列表增加字母下画线上述索引从0开始计算。当然在将所选择的字母处理成带有下划线时必须适度选择具有代表性的字母通常会是字符串的第一个字母例如File菜单可以选择FHelp菜单可以选择H等等。有时候会发生字符串的第一个字母与先前的字母重复例如Save的S与Save As的S这时第二个出现的字符串可以适当选择其它字母可参考下列实例。下面程序实例ch16_6重新设计ch16_5为菜单泪飙和列表命令建立快捷键。from tkinter import * from tkinter import messagebox def newFile(): messagebox.showinfo(New File, 新建文档) def openFile(): messagebox.showinfo(New File, 打开文档) def saveFile(): messagebox.showinfo(New File, 保存文档) def saveAsFile(): messagebox.showinfo(New File, 另存为) def aboutMe(): messagebox.showinfo(Help File, 关于我) root Tk() root.title(ch16_6) root.geometry(300x180) menubar Menu(root) # 建立最上层菜单 # 建立菜单类别对象并将此菜单类别命名为File filemenu Menu(menubar) menubar.add_cascade(labelFile, menufilemenu, underline0) # 在file菜单内建立菜单列表 filemenu.add_command(labelNew File, commandnewFile, underline0) filemenu.add_command(labelOpen File, commandopenFile, underline0) filemenu.add_separator() filemenu.add_command(labelSave, commandsaveFile, underline0) filemenu.add_command(labelSave As, commandsaveAsFile, underline5) filemenu.add_separator() filemenu.add_command(labelExit!, commandroot.destroy, underline0) # 建立菜单类别对象并将此菜单类别命名为Help helpmenu Menu(menubar) menubar.add_cascade(labelHelp, menuhelpmenu, underline0) # 在help菜单内建立菜单列表 helpmenu.add_command(labelAbout me, commandaboutMe, underline1) root.config(menumenubar) # 显示菜单对象 root.mainloop()执行结果可以看到File的F和Help的H字母含下划线按F键可以开启File菜单。上述左图中按N键可以执行New File功能。16-6 Ctrl快捷键在设计菜单列表时也可以在指令右边设计CtrlX之类的快捷键X是代表一个快捷键的英文字母要设计这类操作可以借助accelerator参数然后再使用第11章所学的bind()方法将此快捷键绑定一个callback()方法。为了使程序简化可以借助Ctrl快捷键的方法下面的ch16_7简化了ch16_6。下面程序实例ch16_7设计File菜单的New File子菜单可以按CtrlN组合键。from tkinter import * from tkinter import messagebox def newFile(): messagebox.showinfo(New File, 新建文档) root Tk() root.title(ch16_7) root.geometry(300x180) menubar Menu(root) # 建立最上层菜单 # 建立菜单类别对象并将此菜单类别命名为File filemenu Menu(menubar) menubar.add_cascade(labelFile, menufilemenu, underline0) # 在file菜单内建立菜单列表 filemenu.add_command(labelNew File, commandnewFile, acceleratorCtrlN) filemenu.add_separator() filemenu.add_command(labelExit!, commandroot.destroy, underline0) root.config(menumenubar) # 显示菜单对象 root.bind(Control-N, lambda event: messagebox.showinfo(New File, 新建文档)) root.mainloop()执行结果在上述第21、22行是执行ctrlN快捷键的绑定由于所绑定事件会回传event事件给callback()方法所以无法直接调用第4、5行的newFile()方法因为newFile()方法没有传递任何参数碰上这种问题如果凭直觉再建立一个专供此快捷键使用的方法此例中使用Lambda表达式处理以简化整个程序的设计。16-7 建立子菜单建立菜单时所使用的概念如下。menubar Menu(root) filemenu Menu(menubar) menu.add_cascade(labelFile, menufilemenu)上述是建立File菜单。所谓的建立子菜单就是在File菜单内另外建立一个子菜单。如果所要建立的子菜单是Find子菜单所要建的对象是findmenu此时可以使用下列命令。findmenu Menu(filemenu) xxx # 这是建立子菜单列表 xxx # 这是建立子菜单列表 filemenu.add_cascade(labelFind, menufindmenu)下面程序实例ch16_8在File菜单内建立Find子菜单这个子菜单内有Find Next和Find Pre命令from tkinter import * from tkinter import messagebox def findNext(): messagebox.showinfo(Fine Next, 查找下一个) def findPre(): messagebox.showinfo(Fine Next, 查找前一个) root Tk() root.title(ch16_8) root.geometry(300x180) menubar Menu(root) # 建立最上层菜单 # 建立菜单类别对象并将此菜单类别命名为File filemenu Menu(menubar) menubar.add_cascade(labelFile, menufilemenu, underline0) # 在file菜单内建立菜单列表 # 首先在File菜单内建立Find子菜单对象 findmenu Menu(filemenu, tearoff0) # 取消分隔线 findmenu.add_command(labelFind Next, commandfindNext) findmenu.add_command(labelFind Pre, commandfindPre) filemenu.add_cascade(labelFind, menufindmenu) # 下面是增加分隔线和建立Exit!子菜单 filemenu.add_separator() # 添加分隔线 filemenu.add_command(labelExit!, commandroot.destroy, underline0) root.config(menumenubar) # 显示菜单对象 root.mainloop()执行结果由于在子菜单的设计中一般为省略虚线分隔线设计所以在第19行的menu()方法中增加了tearoff0.16-8 建立弹出式菜单当使用Windows操作系统时可以在桌面上单击鼠标右键此时会弹出一个菜单这就是弹出式菜单Popupmenu有人将此菜单称为快捷菜单。设计这类菜单与先前需在窗口的menubar区建立菜单类别有一些差异建立好Menu对象后可以直接利用此对象建立指令列表最后再单击鼠标右键操作绑定显示弹出菜单即可。popupmenu Menu(root, tearoffFalse) # 隐藏虚线分隔线 popupmenu.add_command(label xx, command yy) # 建立指令列表 ..., root.bind(Button-3, callback) # 绑定单击鼠标右键显示弹出菜单下面程序实例ch16_9设计弹出菜单这个弹出菜单中有两个子菜单一个是Minimize可以将窗口缩成图标另一个是Exit结束程序。from tkinter import * def minimizeIcon(): # 缩小窗口为图标 root.iconify() def showPopupMenu(event): # 显示弹出菜单 popupmenu.post(event.x_root, event.y_root) root Tk() root.title(ch16_9) root.geometry(300x180) popupmenu Menu(root, tearoffFalse) # 建立弹出菜单对象 # 在弹出菜单内建立两个指令列表 popupmenu.add_command(labelMinimize, commandminimizeIcon) popupmenu.add_command(labelExit, commandroot.destroy) # 单击鼠标右键绑定显示弹出菜单 root.bind(Button-3, showPopupMenu) root.mainloop()执行结果上述第4行的iconify()是最小化窗口第7行的post()方法是由popupmenu对象启动相当于可以在鼠标光标位置(event.x_root, event.y_root)弹出此菜单。16-9 add_checkbutton()在设计菜单列表时也可以将命令用复选框(checkbutton)方式表示也称为Check menu button下面将用程序实例讲解。程序实例ch16_10在执行时在窗口下方可以看到状态栏View菜单中的Status其实就是用的复选框命令。上述工作原理是当Status状态为True时Status左边可以有勾选符号同时窗口下方会有状态栏可参考上方左图。当Status状态是False时左边没有勾选符号同时窗口下方不会有状态栏可参考上方右图。Check menu button的工作原理和Widget对象Checkbutton相同单击可以切换状态是True或False。下面程序实例ch16_10设计当Status为True时可以显示状态栏当Status为False时可以隐藏状态栏这个程序的状态栏使用标签Label方式处理可以参考29~32行。from tkinter import * def status(): if demoStatus.get(): # 设定是否显示状态栏 statusLabel.pack(sideBOTTOM, fillX) else: statusLabel.pack_forget() # 隐藏标签栏 root Tk() root.title(ch16_10) root.geometry(300x180) menubar Menu(root) # 建立最上层菜单 # 建立菜单类别对象并将此菜单类别命名为File filemenu Menu(menubar, tearoffFalse) menubar.add_cascade(labelFile, menufilemenu) # 在File菜单内建立菜单列表Exit filemenu.add_command(labelExit, commandroot.destroy) # 建立菜单类别对象并将此菜单类别命名为View viewmenu Menu(menubar, tearoffFalse) menubar.add_cascade(labelView, menuviewmenu) # 在View菜单内创建Check menu button demoStatus BooleanVar() demoStatus.set(True) viewmenu.add_checkbutton(labelStatus, commandstatus, variabledemoStatus) root.config(menumenubar) # 显示菜单对象 statusVar StringVar() statusVar.set(显示) statusLabel Label(root, textvariablestatusVar, reliefraised) statusLabel.pack(sidebottom, fillx) root.mainloop()执行结果 可参考前面的讲解。上述程序的重点如下第23 ~ 26行在View菜单内使用add_checkbutton()创建Check menu button此对象名称是Status同时使用demoStatus布尔变量记录目前状态是True或False这个Status对象当有状态改变时会执行Status()方法。在第3 ~ 7 行的status()方法中如果目前demoStatus是True执行第5行包装显示窗口的标签状态栏相当于显示statusLabel。如果目前demoStatus是False执行第7行的statusLabel.pack_forget()这个方法可以隐藏标签状态栏。16-10 建立工具栏Toolbar在前面章节中已经学会使用将一系列类似命令组成菜单。在窗口程序设计中另一个很重要的概念是将常用的命令组成工具栏放在窗口内以方便用户随时调用。tkinter模块没有提供Toolbar模块不过我们可以使用Frame建立工具栏。下面程序实例ch16_11这个程序会建立一个File菜单菜单内有Exit命令。这个程序也建立一个工具栏在工具栏内有exitBtn按钮。这个程序不论是执行File菜单的Exit命令或是单击工具栏中的exitBtn按钮都可以让程序结束。from tkinter import * root Tk() root.title(ch16_11) root.geometry(300x180) menubar Menu(root) # 建立最上层菜单 # 建立菜单类别对象并将此菜单类别命名为File filemenu Menu(menubar, tearoffFalse) menubar.add_cascade(labelFile, menufilemenu) # 在File菜单内建立菜单列表Exit filemenu.add_command(labelExit, commandroot.destroy) # 建立工具栏 toolbar Frame(root, reliefRAISED, borderwidth3) # 在工具栏内建立按钮 tbPng PhotoImage(filetubiao.png) exitBtn Button(toolbar, imagetbPng, commandroot.destroy) exitBtn.pack(sideLEFT, padx3, pady3) # 包装按钮 toolbar.pack(sideTOP, fillX) # 包装工具栏 root.config(menumenubar) # 显示菜单对象 root.mainloop()运行结果