I am trying to write an application which requires some logic to be performed every time a particular frame is shown. Taking advice from the questions here, here and here, I have come up with some code structured like this:
import tkinter as tk
from tkinter import ttk
class MainApp(tk.Tk):
def __init__(self, *args, **kwargs) -> None:
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.madlibs_source = ""
self.frames = {
"PageOne": PageOne(
parent=container,
controller=self,
),
"PageTwo": PageTwo(
parent=container,
controller=self,
),
"PageThree": PageThree(
parent=container,
controller=self,
),
}
self.frames["PageOne"].grid()
def show_frame(self, page_name: str) -> None:
'''Show a frame for the given page name'''
for frame in self.frames.values():
frame.grid_remove()
frame = self.frames[page_name]
frame.grid()
frame.event_generate("<<ShowFrame>>")
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
page_two_button = ttk.Button(
self,
text="Page 2",
command=lambda: self.controller.show_frame("PageTwo"),
)
page_two_button.pack(padx="10", pady="10")
page_three_button = ttk.Button(
self,
text="Page 3",
command=lambda: self.controller.show_frame("PageThree"),
)
page_three_button.pack(padx="10", pady="10")
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
page_three_button = ttk.Button(
self,
text="Page 3",
command=lambda: self.controller.show_frame("PageThree"),
)
page_three_button.pack(padx="10", pady="10")
class PageThree(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
some_label = tk.Label(self, text="This is page three")
some_label.pack()
self.bind("<<ShowFrame>>", self.frame_shown)
def frame_shown(self, event):
print("Doing something")
if __name__ == "__main__":
root = MainApp()
root.mainloop()
I would expect from this that whenever page three is shown, the frame_shown method would be run and "Doing Something" would be output to the console, but this doesn't seem to to be the case. Can anybody point out where I'm going wrong?