[Tkinter] Unable to Access global Variable when switching between frames - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: GUI (https://python-forum.io/forum-10.html) +--- Thread: [Tkinter] Unable to Access global Variable when switching between frames (/thread-22180.html) |
Unable to Access global Variable when switching between frames - tziyong - Nov-02-2019 Hi all I have tkinter code involving multiple frames. My goal is to have PageOne's label show the text of the button clicked in StartPage. I created a function to change the global variable and have PageOne's class access the global variable after clicking on the button in StartPage. However, the frame in PageOne does not show the label even when the variable is changed. I am unsure of how to resolve this issue. Does the error due to my main class MiniProject __init__ function? import tkinter as tk var = "" def changename(name): #function for changing global variable global var var = name return var class MiniProject(tk.Tk): #baseline code for adding/switching pages https://pythonprogramming.net/change-show-new-frame-tkinter/ def __init__(self, *args, **kwargs): #takes in any argument /keyword arguments 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.frames = {} for F in (StartPage, PageOne): frame = F(container, self) self.frames[F] = frame frame.grid(row=0, column=0, sticky="nsew") self.show_frame(StartPage) def show_frame(self, cont): frame = self.frames[cont] frame.tkraise() class StartPage(tk.Frame): #Front page with buttons 1 to 5 def __init__(self, parent, controller): tk.Frame.__init__(self, parent) for x in [1,2,3,4,5]: #clicking button should bring me to PageOne with label as button number instead of "..." button = tk.Button(self, text=x, \ command= lambda j = x: [changename(name = j),controller.show_frame(PageOne)]) #code that changes variable to button number button.pack() class PageOne(tk.Frame): def __init__(self, parent, controller): global var tk.Frame.__init__(self, parent) label = tk.Label(self, text=var) #Supposed to display button number label.pack(pady=10,padx=10) button1 = tk.Button(self, text="TO HOME", command= lambda: controller.show_frame(StartPage)) button1.pack() app = MiniProject(var) app.mainloop() RE: Unable to Access global Variable when switching between frames - balenaucigasa - Nov-03-2019 from tkinter import * import tkinter as tk var = "0" def changename(name): #function for changing global variable global var var = name print("your 'def changename' is: ", var) return var class MiniProject(tk.Tk): #baseline code for adding/switching pages https://pythonprogramming.net/change-show-new-frame-tkinter/ def __init__(self, *args, **kwargs): #takes in any argument /keyword arguments 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.title("Main") self.frames = {} for F in (StartPage, PageM): frame = F(container, self) self.frames[F] = frame frame.grid(row=0, column=5, sticky="nsew") self.show_frame(StartPage) def show_frame(self, cont): frame = self.frames[cont] global var print("your 'def show_frame' is: ", var) #print(frame.__dict__) ##### #print(frame.__dict__.keys()) #print(dir(frame._tclCommands)) frame.tkraise() class StartPage(tk.Frame): #Front page with buttons 1 to 5 def __init__(self, parent, controller): tk.Frame.__init__(self, parent) for x in [1,2,3,4,5]: #clicking button should bring me to PageOne with label as button number instead of "..." button = tk.Button(self, justify=CENTER, text=str(x), \ command= lambda j = x: [changename(name = j),controller.show_frame(PageM)]) #code that changes variable to button number button.pack(side = LEFT) class PageM(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) var = IntVar() var.set(tk.Frame) label = tk.Label(self, textvariable=var) #Supposed to display button number label.pack(pady=10,padx=10) button1 = tk.Button(self, text="TO HOME", command= lambda: controller.show_frame(StartPage)) button1.pack() app = MiniProject(var) app.mainloop()StartPage is implemented incorrectly. You must have 5 classes for the 5 buttons created. Why? Each button creates a frame. 1 button = 1 frame = 1 class You can find the original along with other suggestions here: import tkinter as tk # python 3 from tkinter import font as tkfont # python 3 #import Tkinter as tk # python 2 #import tkFont as tkfont # python 2 class SampleApp(tk.Tk): def __init__(self, *args, **kwargs): tk.Tk.__init__(self, *args, **kwargs) self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic") # 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) container.pack(side="top", fill="both", expand=True) container.grid_rowconfigure(0, weight=1) container.grid_columnconfigure(0, weight=1) self.frames = {} for F in (StartPage, PageOne, PageTwo): page_name = F.__name__ frame = F(parent=container, controller=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") self.show_frame("StartPage") def show_frame(self, page_name): '''Show a frame for the given page name''' frame = self.frames[page_name] frame.tkraise() class StartPage(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) self.controller = controller label = tk.Label(self, text="This is the start page", font=controller.title_font) label.pack(side="top", fill="x", pady=10) button1 = tk.Button(self, text="Go to Page One", command=lambda: controller.show_frame("PageOne")) button2 = tk.Button(self, text="Go to Page Two", command=lambda: controller.show_frame("PageTwo")) button1.pack() button2.pack() class PageOne(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) self.controller = controller label = tk.Label(self, text="This is page 1", font=controller.title_font) label.pack(side="top", fill="x", pady=10) button = tk.Button(self, text="Go to the start page", command=lambda: controller.show_frame("StartPage")) button.pack() class PageTwo(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) self.controller = controller label = tk.Label(self, text="This is page 2", font=controller.title_font) label.pack(side="top", fill="x", pady=10) button = tk.Button(self, text="Go to the start page", command=lambda: controller.show_frame("StartPage")) button.pack() if __name__ == "__main__": app = SampleApp() app.mainloop() |