¿Cómo puedo hacer un método que se ejecuta cada vez que se muestra un marco en tkinter

Tengo una aplicación de GUI que tiene varias ventanas y botones para avanzar y retroceder. Para hacer esto, estoy usando un controlador y elevando los marcos a la parte superior con cada cambio de ventana. Aquí está mi código para el controlador y un marco típico.

import Tkinter as tk # python from tkFileDialog import askopenfilename, asksaveasfilename from analyzer import Options TITLE_FONT = ("Helvetica", 18, "bold") class TennisProgram(tk.Tk): def __init__(self, *args, **kwargs): tk.Tk.__init__(self, *args, **kwargs) # the container is where we'll stack a bunch of frames # on top of each other, then the one we want visible # will be raised above the others container = tk.Frame(self) #Allow the window to be resized # container.resizable(width=True, height=True) container.pack(side="top", fill="both", expand=True) container.grid_rowconfigure(0, weight=1) container.grid_columnconfigure(0, weight=1) #List of options bundles. One bundle for each video self.options_bundle_list = {} self.frames = {} #Init empty array to hold the list of files #Placed in the container so that all views can access it self.files = [] for F in (UploadPage, AnalysisOptionsPage, FormAnalysisOptions, MatchAnalysisOptions, MatchAnalysisOptionsPage2, OutputPage, ProcessingPage): page_name = F.__name__ frame = F(container, self) self.frames[page_name] = frame # put all of the pages in the same location; # the one on the top of the stacking order # will be the one that is visible. frame.grid(row=0, column=0, sticky="nsew") # Name the window self.title("Tennis Analyzer") self.show_frame("UploadPage") def show_frame(self, page_name): '''Show a frame for the given page name''' frame = self.frames[page_name] frame.tkraise() class UploadPage(tk.Frame): #TODO Add logic to remove a file path from the list def __init__(self, parent, controller): tk.Frame.__init__(self, parent) self.controller = controller self.createView() def createView(self): label = tk.Label(self, text="Upload Videos for Analysis", font=TITLE_FONT) label.pack(side="top", fill="x", pady=10) #Listbox to display the list of files to be processed self.path_list = tk.Listbox(self) #Additional options allow listbox to expand as the window is resized self.path_list.pack(fill=tk.BOTH ,expand=True) for path in self.controller.files: self.path_list.insert(tk.END, path) add_vidoes_button = tk.Button(self, text="Add Videos", command=self.choose_files) continue_button = tk.Button(self, text="Continue", command=lambda: self.controller.show_frame("AnalysisOptionsPage")) add_vidoes_button.pack(side=tk.TOP) continue_button.pack(side=tk.BOTTOM) def choose_files_paths(self): #don't want a full GUI, so keep the root window from appearing #self.controller.withdraw() #Get a file name from the user filename = askopenfilename() #Add it to the list of files to be processed self.controller.files.append(filename) self.path_list.insert(tk.END, filename) 

El código que escribo en init se ejecuta una vez y crea la vista, pero me preguntaba si sería posible tener una función que se ejecute cada vez que se suba el marco, similar a una función onResume en Android. Me gustaría hacer esto en caso de que algunos datos subyacentes hayan cambiado, como en esta página de carga. Por ejemplo, si un elemento se elimina de la matriz que llena la vista de lista, me gustaría poder actualizarlo.

Tkinter tiene eventos de bajo nivel, como y

que deberían activarse cuando cambian las páginas. Desafortunadamente, estos no funcionan de manera confiable en todas las plataformas.

La solución más simple y robusta es generar tu propio evento. Primero, cambie show_frame para enviar un evento a una ventana cuando se muestre:

 def show_frame(self, page_name): ... frame.event_generate("<>") 

A continuación, cada página puede vincularse a este evento si necesita ser notificado cuando se hace visible:

 class UploadPage(tk.Frame): def __init__(self, parent, controller): ... self.bind("<>", self.on_show_frame) def on_show_frame(self, event): print("I am being shown...")