In this post, we will see how to create a menu using Tkinter.
Let’s start by creating a file called menu.py and we define a menu bar called menu_bar:
[MENU.PY]
import tkinter as tk
# Definition of the main application window
window = tk.Tk()
window.title("Menu with Pages")
window.geometry("800x600")
# Definition of a menu bar
menu_bar = tk.Menu(window)
window.config(menu=menu_bar)
# Start the main event loop
window.mainloop()
If we run the application, the following will be the result:

We can see that no menu is shown because we didn’t define any menu items.
Let’s add two menu items:
[MENU.PY]
import tkinter as tk
# Definition of the main application window
window = tk.Tk()
window.title("Menu with Pages")
window.geometry("800x600")
# Definition of a menu bar
menu_bar = tk.Menu(window)
window.config(menu=menu_bar)
# Create a functions1 menu
functions1 = tk.Menu(menu_bar, tearoff=0)
menu_bar.add_cascade(label="Functions1", menu=functions1)
# Create a functions2 menu
functions2 = tk.Menu(menu_bar, tearoff=0)
menu_bar.add_cascade(label="Functions2", menu=functions2)
# Start the main event loop
window.mainloop()
If we run the application, the following will be the result:

Now, we will add some menu options in the two menu items:
[MENU.PY]
import tkinter as tk
# Definition of the main application window
window = tk.Tk()
window.title("Menu with Pages")
window.geometry("800x600")
# Function to show Page A
def show_page_A():
hide_all_frames() # Hide all frames
pageA_frame.place(x=0, y=0) # Show Page A frame at position (0, 0)
# Function to show Page B
def show_page_B():
hide_all_frames() # Hide all frames
pageB_frame.place(x=0, y=0) # Show Page B frame at position (0, 0)
# Function to show Page C
def show_page_C():
hide_all_frames() # Hide all frames
pageC_frame.place(x=0, y=0) # Show Page C frame at position (0, 0)
# Function to hide all frames
def hide_all_frames():
for frame in [pageA_frame, pageB_frame, pageC_frame]:
frame.place_forget()
# Definition of a menu bar
menu_bar = tk.Menu(window)
window.config(menu=menu_bar)
# Create a functions1 menu
functions1 = tk.Menu(menu_bar, tearoff=0)
# Adding 2 items in the functions1 menu item
functions1.add_command(label="Functions1_A", command=show_page_A)
functions1.add_separator()
functions1.add_command(label="Functions1_B", command=show_page_B)
menu_bar.add_cascade(label="Functions1", menu=functions1)
# Create a functions2 menu
functions2 = tk.Menu(menu_bar, tearoff=0)
functions2.add_command(label="Functions2_C", command=show_page_C)
# Function used to quit the application
functions2.add_command(label="Exit", command=window.quit)
menu_bar.add_cascade(label="Functions2", menu=functions2)
# Frames in Tkinter are a way to organize and group widgets together.
# They act as containers that can hold other widgets like labels, buttons, entry fields, and so on.
# Frames are useful for creating well-structured and organized layouts within your GUI applications.
pageA_frame = tk.Frame(window, width=800, height=600)
labelA = tk.Label(pageA_frame, text="Page A Content")
labelA.place(x=50, y=50)
buttonA = tk.Button(pageA_frame, text="Button A")
buttonA.place(x=100, y=100)
pageB_frame = tk.Frame(window, width=800, height=600)
labelB = tk.Label(pageB_frame, text="Page B Content")
labelB.place(x=50, y=50)
buttonB = tk.Button(pageB_frame, text="Button B")
buttonB.place(x=100, y=100)
pageC_frame = tk.Frame(window, width=800, height=600)
labelC = tk.Label(pageC_frame, text="Page C Content")
labelC.place(x=50, y=50)
buttonC = tk.Button(pageC_frame, text="Button C")
buttonC.place(x=100, y=100)
# Start the main event loop
window.mainloop()
If we run the application, the following will be the result:




Finally, we add a method called “changeMessageC” that we will use when we click the “Button C”:
[MENU.PY]
import tkinter as tk
# Definition of the main application window
window = tk.Tk()
window.title("Menu with Pages")
window.geometry("800x600")
# Function to show Page A
def show_page_A():
hide_all_frames() # Hide all frames
pageA_frame.place(x=0, y=0) # Show Page A frame at position (0, 0)
# Function to show Page B
def show_page_B():
hide_all_frames() # Hide all frames
pageB_frame.place(x=0, y=0) # Show Page B frame at position (0, 0)
# Function to show Page C
def show_page_C():
hide_all_frames() # Hide all frames
pageC_frame.place(x=0, y=0) # Show Page C frame at position (0, 0)
# Function to hide all frames
def hide_all_frames():
for frame in [pageA_frame, pageB_frame, pageC_frame]:
frame.place_forget()
# Definition of a menu bar
menu_bar = tk.Menu(window)
window.config(menu=menu_bar)
# Create a functions1 menu
functions1 = tk.Menu(menu_bar, tearoff=0)
# Adding 2 items in the functions1 menu item
functions1.add_command(label="Functions1_A", command=show_page_A)
functions1.add_separator()
functions1.add_command(label="Functions1_B", command=show_page_B)
menu_bar.add_cascade(label="Functions1", menu=functions1)
# Create a functions2 menu
functions2 = tk.Menu(menu_bar, tearoff=0)
functions2.add_command(label="Functions2_C", command=show_page_C)
# Function used to quit the application
functions2.add_command(label="Exit", command=window.quit)
menu_bar.add_cascade(label="Functions2", menu=functions2)
# Frames in Tkinter are a way to organize and group widgets together.
# They act as containers that can hold other widgets like labels, buttons, entry fields, and so on.
# Frames are useful for creating well-structured and organized layouts within your GUI applications.
pageA_frame = tk.Frame(window, width=800, height=600)
labelA = tk.Label(pageA_frame, text="Page A Content")
labelA.place(x=50, y=50)
buttonA = tk.Button(pageA_frame, text="Button A")
buttonA.place(x=100, y=100)
pageB_frame = tk.Frame(window, width=800, height=600)
labelB = tk.Label(pageB_frame, text="Page B Content")
labelB.place(x=50, y=50)
buttonB = tk.Button(pageB_frame, text="Button B")
buttonB.place(x=100, y=100)
pageC_frame = tk.Frame(window, width=800, height=600)
labelC = tk.Label(pageC_frame, text="Page C Content")
labelC.place(x=50, y=50)
# Definition of the method called when we click on Button C
def changeMessageC():
# Update the label's text
labelC.config(text=f"You pushed the button C")
buttonC = tk.Button(pageC_frame, text="Button C", command=changeMessageC)
buttonC.place(x=100, y=100)
# Start the main event loop
window.mainloop()
If we run the application, the following will be the result:


The last thing that I want to show, is how to handle a frame defined in external file.
We start creating a file called ExternalFrame.py, so defined:
[EXTERNALFRAME.PY]
import tkinter as tk
class ExternalFrame(tk.Frame):
def __init__(self, parent):
super().__init__(parent, width=800, height=600)
labelD = tk.Label(self, text="This is a frame from an external file")
labelD.place(x=150, y=150)
Then, we modify the file Main.py:
[MAIN.PY]
import tkinter as tk
from ExternalFrame import ExternalFrame
# Definition of the main application window
window = tk.Tk()
window.title("Menu with Pages")
window.geometry("800x600")
# Function to show Page A
def show_page_A():
hide_all_frames() # Hide all frames
pageA_frame.place(x=0, y=0) # Show Page A frame at position (0, 0)
# Function to show Page B
def show_page_B():
hide_all_frames() # Hide all frames
pageB_frame.place(x=0, y=0) # Show Page B frame at position (0, 0)
# Function to show Page C
def show_page_C():
hide_all_frames() # Hide all frames
pageC_frame.place(x=0, y=0) # Show Page C frame at position (0, 0)
# Function to show Page D
def show_page_D():
hide_all_frames() # Hide all frames
pageD_frame.place(x=0, y=0) # Show Page C frame at position (0, 0)
# Function to hide all frames
def hide_all_frames():
for frame in [pageA_frame, pageB_frame, pageC_frame, pageD_frame]:
frame.place_forget()
# Definition of a menu bar
menu_bar = tk.Menu(window)
window.config(menu=menu_bar)
# Create a functions1 menu
functions1 = tk.Menu(menu_bar, tearoff=0)
# Adding 2 items in the functions1 menu item
functions1.add_command(label="Functions1_A", command=show_page_A)
functions1.add_separator()
functions1.add_command(label="Functions1_B", command=show_page_B)
menu_bar.add_cascade(label="Functions1", menu=functions1)
# Create a functions2 menu
functions2 = tk.Menu(menu_bar, tearoff=0)
functions2.add_command(label="Functions2_C", command=show_page_C)
functions2.add_command(label="Functions2_D", command=show_page_D)
# Function used to quit the application
functions2.add_command(label="Exit", command=window.quit)
menu_bar.add_cascade(label="Functions2", menu=functions2)
# Frames in Tkinter are a way to organize and group widgets together.
# They act as containers that can hold other widgets like labels, buttons, entry fields, and so on.
# Frames are useful for creating well-structured and organized layouts within your GUI applications.
pageA_frame = tk.Frame(window, width=800, height=600)
labelA = tk.Label(pageA_frame, text="Page A Content")
labelA.place(x=50, y=50)
buttonA = tk.Button(pageA_frame, text="Button A")
buttonA.place(x=100, y=100)
pageB_frame = tk.Frame(window, width=800, height=600)
labelB = tk.Label(pageB_frame, text="Page B Content")
labelB.place(x=50, y=50)
buttonB = tk.Button(pageB_frame, text="Button B")
buttonB.place(x=100, y=100)
pageC_frame = tk.Frame(window, width=800, height=600)
labelC = tk.Label(pageC_frame, text="Page C Content")
labelC.place(x=50, y=50)
# Definition of the method called when we click on Button C
def changeMessageC():
# Update the label's text
labelC.config(text=f"You pushed the button C")
buttonC = tk.Button(pageC_frame, text="Button C", command=changeMessageC)
buttonC.place(x=100, y=100)
# External Frame
pageD_frame = ExternalFrame(window)
# Start the main event loop
window.mainloop()
We have done and now, if we run the application, the following will be the result:

