How can I make a method that runs every time a frame is displayed in tkinter

I have a gui application that has several windows and buttons to go back and forth. To do this, I use the controller and raise the frames at the top each time the window changes. Here is my controller code and typical frame.

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) 

The code that I write in init runs once and creates a view, but I was wondering if it is possible to have a function that runs every time the frame goes up, like the onResume function in Android. I would like to do this if some basic data has changed, like on this download page. For example, what if an element is removed from an array that fills the list, I would like to update it.

+2
python tkinter
Jan 27 '16 at 4:55
source share
1 answer

Tkinter has low-level events, such as <Visibility> and <Map> which should fire when pages change. Unfortunately, they do not work reliably on all platforms.

The simplest and most reliable solution is to create your own event. You can create and bind a custom event by specifying the event inside << and >> (for example: <<ShowFrame>> ).

First change show_frame to send an event to the window when it is displayed:

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

Further, each page can be attached to this event if it should be notified when it becomes visible:

 class UploadPage(tk.Frame): def __init__(self, parent, controller): ... self.bind("<<ShowFrame>>", self.on_show_frame) def on_show_frame(self, event): print("I am being shown...") 
+9
Jan 27 '16 at 11:35
source share



All Articles