Tkinter Tutorial - Menubar
One of the most common elements in the GUI is the menu bar. A menu bar is normally under the title bar to display the series of menus. After clicking one of the top-level menus, a sub-menu will be extended to display more relevant menu items. A sub-menu is normally bound to the specific command like open, close, save or quit.
Tkinter Basic Menubar
We will create our first menubar example that has File menu as in most editors. We only include Open, Save and Quit sub-menus for simplicity.
import tkinter as tk
app = tk.Tk()
app.geometry("300x200")
app.title("Basic Menu Bar")
menubar = tk.Menu(app)
filemenu = tk.Menu(menubar)
filemenu.add_command(label="Open")
filemenu.add_command(label="Save")
filemenu.add_command(label="Exit")
menubar.add_cascade(label="File", menu=filemenu)
app.config(menu=menubar)
app.mainloop()

menubar = tk.Menu(app)
The given parameter of the Menu is the parent widget of the created menu. The code line above means that the menu widget menubar will be the top level of the frame app.
filemenu = tk.Menu(menubar)
Similarly, filemenu is the menu of the widget menubar, or sub menu of the frame app.
filemenu.add_command(label="Open")
add_command adds the commands to the menu filemenu. label is the text displayed in the sub menu.
menubar.add_cascade(label="File", menu=filemenu)
filemenu is added to menubar with the command add_cascade. File is the menu label displayed in the top level of the frame app.
app.config(menu=menubar)
Although menubar is created to be child widget of app as we explained above, you still need to config it to be the menu of app. Otherwise, no menu bar will be shown in the GUI.
It doesn’t respond at all if you click the options like Open or Save in the sub menu of File because there is no command attached to them yet. We will make the command functional in the next session.
Tkinter Menubar Command
import tkinter as tk
from tkinter import filedialog
def onOpen():
print(
filedialog.askopenfilename(
initialdir="/",
title="Open file",
filetypes=(("Python files", "*.py;*.pyw"), ("All files", "*.*")),
)
)
def onSave():
print(
filedialog.asksaveasfilename(
initialdir="/",
title="Save as",
filetypes=(("Python files", "*.py;*.pyw"), ("All files", "*.*")),
)
)
app = tk.Tk()
app.geometry("300x200")
app.title("Menu Bar Command")
menubar = tk.Menu(app)
filemenu = tk.Menu(menubar, tearoff=0)
filemenu.add_command(label="Open", command=onOpen)
filemenu.add_command(label="Save", command=onSave)
filemenu.add_command(label="Exit", command=app.quit)
menubar.add_cascade(label="File", menu=filemenu)
app.config(menu=menubar)
app.mainloop()
filemenu = tk.Menu(menubar, tearoff=0)
tearoff is set to be 1 by default and it would detach menus from the main window to create a floating menu if the dotted lines at the top is clicked. Here it is set to be 0 to disable this floating feature.
filemenu.add_command(label="Open", command=onOpen)
onOpen function is bound to the menu Open, and will be called when Open is clicked.
def onOpen():
print(
filedialog.askopenfilename(
initialdir="/",
title="Open file",
filetypes=(("Python files", "*.py;*.pyw"), ("All files", "*.*")),
)
)
This function displays the open dialog and returns the selected filename. We don’t really open the file in our example but to print its filename.
tkfiledialog has three functions,
| Function | Parameters | Description |
|---|---|---|
.askopenfilename |
Directory, Title, Extension | To open file: Dialog that requests selection of an existing file. |
.asksaveasfilename |
Directory, Title, Extension | To save file: Dialog that requests creation or replacement of a file. |
.askdirectory |
None | To open directory |
filemenu.add_command(label="Exit", command=app.quit)
Tkinter has an internal quit function that quits the root GUI. We could simply bind this existing function to Exit rather than creating our own exit function.
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook