Python Forum
[Tkinter] Unable to Access global Variable when switching between frames
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] Unable to Access global Variable when switching between frames
#1
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()
Reply
#2
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()
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Switching from tkinter to gtk is difficult! snakes 1 1,422 Aug-08-2022, 10:35 PM
Last Post: woooee
  [Tkinter] tkinter global variable chalao_adda 6 10,851 Nov-14-2020, 05:37 AM
Last Post: chalao_adda
  Global Variable in Event Function? What am I doing wrong here? p_hobbs 1 3,435 Nov-13-2019, 02:50 PM
Last Post: Denni
  [Tkinter] Call a function when switching layouts 4096 0 3,505 Sep-22-2019, 07:39 PM
Last Post: 4096
  [PyGUI] Switching between two frames using Tkinter jenkins43 1 4,582 Jul-17-2019, 10:53 AM
Last Post: metulburr
  [Tkinter] switching frames nick123 2 7,843 Apr-18-2019, 04:50 PM
Last Post: francisco_neves2020
  tkinter - global variable not working albry 2 7,015 Jan-26-2019, 04:22 AM
Last Post: Larz60+
  Problem with pygame not switching the mouse image Mondaythe1st 6 6,628 Jul-26-2017, 10:53 PM
Last Post: metulburr

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020