Python Forum

Full Version: Tkinter bringing variables from 1 frame to another
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello all,
How do you bring a variable from 1 class frame to another? I wish to bring the variables "name 1","name 2" and "name 3" from Class StartPage to Class Manual Page
Some advice would be generally appreciated!
Here's my code.

import tkinter as tk
import time

class BackGroundFrame(tk.Tk):
    def __init__(self,*args,**kwargs):
        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,ManualPage):    
            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):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        instruction = tk.Label(self,text="Welcome to Dispensing GUI")
        instruction.grid(row=0 , column =0,columnspan=3, sticky = "W")
        
        self.action1 = tk.Button(self, text="Retrieve Solution Name",command=lambda:self.retrievesolutions )
        self.action1.grid(row = 0, column = 4,columnspan = 2,sticky= "W")
        
        tk.Label(self,text = "        ").grid(row =1, column = 0,sticky = "W")
        
        tk.Label(self,text = "Solutions to Pumps Allocations").grid(row =2, column = 0,columnspan=10,sticky = "W")
        
        self.typeofsolution1 = tk.Entry(self,width=12) #tk.Entry widget function 
        self.typeofsolution1.grid(row =3, column = 0,sticky = "W")
        tk.Label(self,text = "Pump 1").grid(row =4, column = 0,columnspan=2,sticky = "W") 
        
         
        tk.Label(self,text = "    ").grid(row =3, column = 1,sticky = "W")
        
        self.typeofsolution2 = tk.Entry(self,width=12) #tk.Entry widget function 
        self.typeofsolution2.grid(row =3, column = 2, sticky = "W")
        tk.Label(self,text = "Pump 2").grid(row =4, column = 2,sticky = "W")
        
        tk.Label(self,text = "    ").grid(row =3, column = 3,sticky = "W")
        
        
        self.typeofsolution3 = tk.Entry(self,width=12)
        self.typeofsolution3.grid(row =3, column = 4,sticky = "W")
        tk.Label(self,text = "Pump 3").grid(row =4, column = 4,columnspan=2,sticky = "W") 
        
        tk.Label(self,text = "    ").grid(row =3, column = 5,sticky = "W")
        
        self.typeofsolution4 = tk.Entry(self,width=12)
        self.typeofsolution4.grid(row =3, column = 6,sticky = "W")
        tk.Label(self,text = "Pump 4").grid(row =4, column = 6,columnspan=2,sticky = "W")
        
        self.submitManual = tk.Button(self,text="Manual",command=lambda:controller.show_frame(ManualPage))
        self.submitManual.grid(row =8,rowspan=5, column = 0, columnspan = 4,sticky = "W")
        
        self.submitAutomatic = tk.Button(self,text="Automatic")
        self.submitAutomatic.grid(row =8,rowspan=5, column = 1, columnspan = 2,sticky = "W")
        
    def retrievesolutions(self):
        global name1
        global name2
        global name3
        name1 = self.typeofsolution1.get()
        name2 = self.typeofsolution2.get()
        name3 = self.typeofsolution3.get()  
        print(name1,name2,name3)
            
        
class ManualPage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
         
        self.manualtitle = tk.Label(self, text="Welcome to Manual Dispensing")
        self.manualtitle.grid(row=0 , column =0, columnspan=6, sticky="W")
        
        tk.Label(self,text = "Solution Name    ").grid(row =1, column = 0,sticky="W")
        tk.Label(self,text = "Time Input(s)     ").grid(row =1, column = 2,sticky="w")
        tk.Label(self,text = "Dispense").grid(row =1, column = 5,sticky="W")
    
       
        self.text1 = tk.Text(self, width =10, height = 1)
        self.text1.grid(row = 2, column = 0,columnspan= 10,sticky= "W")
        tk.Label(self,text = "        ").grid(row =3, column = 0,sticky="W")
        
        self.text2 = tk.Text(self, width =10, height = 1)
        self.text2.grid(row = 4, column = 0,columnspan= 10,sticky= "W")
        tk.Label(self,text = "        ").grid(row =5, column = 0,sticky="W")
        
        self.text3 = tk.Text(self, width =10, height = 1)
        self.text3.grid(row = 6, column = 0,columnspan= 10,sticky= "w")
        tk.Label(self,text = "        ").grid(row =7, column = 0,sticky="W")
        
        self.text4 = tk.Text(self, width =10, height = 1)
        self.text4.grid(row = 8, column = 0,columnspan= 10,sticky= "w")
        tk.Label(self,text = "        ").grid(row =9, column = 0,sticky="W")
           
        
        self.submitlol = tk.Button(self,text="Back to Main Menu",command=lambda:controller.show_frame(StartPage))
        self.submitlol.grid(row =10,rowspan=5, column = 0, columnspan = 4,sticky = "W")
        
        
        
        self.timepump1 = tk.Entry(self,width = 10) #entry widget function 
        self.timepump1.grid(row =2, column = 1,columnspan=10,sticky="w")
        
        self.timepump2 = tk.Entry(self,width = 10) #entry widget function 
        self.timepump2.grid(row =4, column = 1,columnspan=10,sticky="w")
        
        self.timepump3 = tk.Entry(self,width = 10) #entry widget function 
        self.timepump3.grid(row =6, column = 1,columnspan=10,sticky="w")
        
        self.timepump4 = tk.Entry(self,width = 10) #entry widget function 
        self.timepump4.grid(row =8, column = 1,columnspan=10,sticky="w")
        
        
        self.submit1 = tk.Button(self, text="Dispense 1")
        self.submit1.grid(row =2, column = 3, columnspan = 10,sticky="w")
        
        self.submit2= tk.Button(self, text="Dispense 2")
        self.submit2.grid(row =4, column = 3, columnspan = 10,sticky="w")
        
        self.submit3 = tk.Button(self, text="Dispense 3")
        self.submit3.grid(row =6, column = 3, columnspan = 10,sticky="w")
        
        self.submit4= tk.Button(self, text="Dispense 4")
        self.submit4.grid(row =8, column = 3, columnspan = 10,sticky="w")
        
        global name1
        global name2
        global name3
        
        self.text1.delete(0.0)
        self.text1.insert(0.0, name1)
            
        self.text2.delete(0.0)
        self.text2.insert(0.0, name2)
            
        self.text3.delete(0.0)
        self.text3.insert(0.0, name3)
        
        
        

        
app = BackGroundFrame()
app.mainloop()
if name1, name2, name3 are strings
comment here

    def retrievesolutions(self):
#        global name1
#        global name2
#        global name3
        name1 = self.typeofsolution1.get()
        name2 = self.typeofsolution2.get()
        name3 = self.typeofsolution3.get()  
        print(name1,name2,name3)
and set it on the begin

import tkinter as tk
import time

name1 = ""
name2 = ""
name3 = ""

class BackGroundFrame(tk.Tk):
....
Hi Axel, thanks for helping me out. However, the name does not seem to print out. Can you kindly help me re-clarify my mistakes? Thank you!
() is missing on self.retrievesolutions

use

        self.action1 = tk.Button(self, text="Retrieve Solution Name",command=lambda: self.retrievesolutions())
1. Your code needs to be refactor. Use list over name1, name2, etc.
2. You pass the frame to ManualPage. So just access StartPage from there.
example code refactor with a few other changes.
import tkinter as tk
import time

class BackGroundFrame(tk.Tk):
    def __init__(self,*args,**kwargs):
        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 klass in [StartPage, ManualPage]:
            self.frames[klass.__name__] = klass(container, self)
            self.frames[klass.__name__].grid(row = 0, column=0,sticky="nsew")
        self.frames["StartPage"].tkraise()

class StartPage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        instruction = tk.Label(self,text="Welcome to Dispensing GUI")
        instruction.grid(row=0 , column =0,columnspan=3, sticky = "W")

        self.action1 = tk.Button(self, text="Retrieve Solution Name",command=lambda:self.push_retrieve_solutions())
        self.action1.grid(row = 0, column = 4,columnspan = 2,sticky= "W")

        tk.Label(self,text = "        ").grid(row =1, column = 0,sticky = "W")
        tk.Label(self,text = "Solutions to Pumps Allocations").grid(row =2, column = 0,columnspan=10,sticky = "W")

        self.typeofsolution = []
        for i in [0, 2, 4, 6]:
            self.create_typeofsolution({"width":12}, {"row":3, "column":i, "sticky":"W"})

        self.submitManual = tk.Button(self,text="Manual",command=lambda:controller.frames["ManualPage"].tkraise())
        self.submitManual.grid(row =8,rowspan=5, column = 0, columnspan = 4,sticky = "W")

        self.submitAutomatic = tk.Button(self,text="Automatic")
        self.submitAutomatic.grid(row =8,rowspan=5, column = 1, columnspan = 2,sticky = "W")

    def create_typeofsolution(self, entry_keys, grid_keys):
        typeofsolution = tk.Entry(self, **entry_keys)
        typeofsolution.grid(**grid_keys)
        self.typeofsolution.append(typeofsolution)

        i = len(self.typeofsolution)
        j = (i - 1) * 2
        tk.Label(self,text = "Pump {0}".format(i)).grid(row =4, column = j,columnspan=2,sticky = "W")
        tk.Label(self,text = "    ").grid(row =3, column = j + 1,sticky = "W")

    def retrieve_solutions(self):
        names = []
        for i in range(3):
            names.append(self.typeofsolution[i].get())

        return names

    def push_retrieve_solutions(self):
        print(self.retrieve_solutions())

class ManualPage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        self.manualtitle = tk.Label(self, text="Welcome to Manual Dispensing")
        self.manualtitle.grid(row=0 , column =0, columnspan=6, sticky="W")

        tk.Label(self,text = "Solution Name    ").grid(row =1, column = 0,sticky="W")
        tk.Label(self,text = "Time Input(s)     ").grid(row =1, column = 2,sticky="w")
        tk.Label(self,text = "Dispense").grid(row =1, column = 5,sticky="W")

        self.text = []
        for i in range(4):
            irow = (i + 1) * 2
            self.text.append(tk.Text(self, width =10, height = 1))
            self.text[-1].grid(row = irow, column = 0,columnspan= 10,sticky= "W")
            tk.Label(self,text = "        ").grid(row = irow + 1, column = 0,sticky="W")

        self.submitlol = tk.Button(self,text="Back to Main Menu",command=lambda:controller.frames["StartPage"].tkraise())
        self.submitlol.grid(row =10,rowspan=5, column = 0, columnspan = 4,sticky = "W")

        self.timepump = []
        for i in range(4):
            irow = (i + 1) * 2
            self.timepump.append(tk.Entry(self,width = 10))
            self.timepump[-1].grid(row = irow, column = 1, columnspan=10, sticky="w")

        self.submit = []
        for i in range(4):
            irow = (i + 1) * 2
            self.submit.append(tk.Button(self, text="Dispense {0}".format(i)))
            self.submit[-1].grid(row = irow, column = 3, columnspan = 10, sticky="w")

        names = controller.frames["StartPage"].retrieve_solutions()
        for i in range(3):
            self.text[i].delete(0.0)
            self.text[i].insert(0.0, names[i])

app = BackGroundFrame()
app.mainloop()
Another solution grabbing class object variables. Make it a class instance.
example
import tkinter as tk
import time

class BackGroundFrame(tk.Tk):
    frames = {} # class instance

    def __init__(self,*args,**kwargs):
        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)

        for klass in [StartPage, ManualPage]:
            BackGroundFrame.frames[klass.__name__] = klass(container)
            BackGroundFrame.frames[klass.__name__].grid(row = 0, column=0,sticky="nsew")
        BackGroundFrame.frames["ManualPage"].tkraise()

class StartPage(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        # other code

    def retrieve_solutions(self):
        return [1,2,3]

class ManualPage(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        print(BackGroundFrame.frames["StartPage"].retrieve_solutions())

        #other code


app = BackGroundFrame()
#app.mainloop()

or create class instance on the fly.
import tkinter as tk
import time

class BackGroundFrame(tk.Tk):
    def __init__(self,*args,**kwargs):
        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)

        # create class instance on the fly
        for klass in [StartPage, ManualPage]:
            setattr(BackGroundFrame, klass.__name__.lower(), klass(container))
            getattr(BackGroundFrame, klass.__name__.lower()).grid(row = 0, column=0,sticky="nsew")
        BackGroundFrame.startpage.tkraise()

class StartPage(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        # other code

    def retrieve_solutions(self):
        return [1,2,3]

class ManualPage(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        print(BackGroundFrame.startpage.retrieve_solutions())

        #other code


app = BackGroundFrame()
#app.mainloop()
I have a DataFrame df_SEM instead of strings and I need to get column names of this DataFrame OptionList = list(df_SEM.columns). and want to populate this OptionsList to Tkinter Optionmenu. I did the same as you have suggested. defined DataFrames. But this returns an error:
opt = tk.OptionMenu(OptionFrame, variable, *OptionList)
TypeError: __init__() missing 1 required positional argument: 'value'

this is the code
OptionList = list(df_SEM.columns)
opt = tk.OptionMenu(OptionFrame, variable, *OptionList)