A question on Stack Overflow asked how to create a tkinter
GUI in Python 3 that would switch between two frames: A start-page and a sub-page.
- Create a Python 3 app which switches between multiple tkinter frames
- Code should be readable and easy to understand
- Scaleable to larger apps where classes are split across multiple files
I answered with a sample app that switches between a main page and two sub-pages. The concept is, have a parent Tk
class (master
) with a switch_frame()
method. When called with a frame class, this method will create a new frame to replace the old one.
# Multi-frame tkinter application v2.3
import tkinter as tk
class SampleApp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self._frame = None
self.switch_frame(StartPage)
def switch_frame(self, frame_class):
"""Destroys current frame and replaces it with a new one."""
new_frame = frame_class(self)
if self._frame is not None:
self._frame.destroy()
self._frame = new_frame
self._frame.pack()
class StartPage(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
tk.Label(self, text="This is the start page").pack(side="top", fill="x", pady=10)
tk.Button(self, text="Open page one",
command=lambda: master.switch_frame(PageOne)).pack()
tk.Button(self, text="Open page two",
command=lambda: master.switch_frame(PageTwo)).pack()
class PageOne(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
tk.Label(self, text="This is page one").pack(side="top", fill="x", pady=10)
tk.Button(self, text="Return to start page",
command=lambda: master.switch_frame(StartPage)).pack()
class PageTwo(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
tk.Label(self, text="This is page two").pack(side="top", fill="x", pady=10)
tk.Button(self, text="Return to start page",
command=lambda: master.switch_frame(StartPage)).pack()
if __name__ == "__main__":
app = SampleApp()
app.mainloop()
While this small example works, I'm concerned this approach could result in circular references if scaled to a larger application with multiple files. (eg: StartPage imports PageOne, PageOne imports StartPage, and so on). I'm also unsure if my example is simple enough, or if it could be simplified further.