Python Forum

Full Version: How can I pass a variable to another class, especially in this situation?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi,
I want to pass the result of the function calculate in line 115 to another class, in this case , PageTwo -> function: pasvariable in line 161, but I do wrong something...

import tkinter as tk
from tkinter import ttk
from tkinter import *
LARGE_FONT = ("Verdana", 12)


    
class reverberationTime(tk.Tk):
    
    
    def __init__(self,*args,**kwargs):
    
       
        tk.Tk.__init__(self, *args, **kwargs)
        
        tk.Tk.wm_title(self, "reverberation time")
        tk.Tk.iconbitmap(self,"C:/Users/PC/Desktop/Icons/speaker.ico")
        
        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, PageThree):
    
            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)
        label = tk.Label(self, text="reverberation time", font=LARGE_FONT)
        label.pack(pady = 10, padx = 10)
        
        button = ttk.Button(self, text="welcome!", 
                            command=lambda: controller.show_frame(PageOne)).pack()

        
class PageOne(tk.Frame):

    
    def __init__(self, parent, controller):
        
    
        tk.Frame.__init__(self, parent)
        NORMAL_FONT=("Arial",11)
        
        title = tk.Label(self, text="Please enter the dimensions", font=LARGE_FONT)
        title.pack(pady = 10, padx = 10)
       
        frame = Frame(self)
        frame.pack(pady=20)
        
        self.lenght = StringVar()
        self.wide = StringVar()
        self.height = StringVar()
        self.v = StringVar()
        
        self.dimensions = Frame(frame)
        self.dimensions.pack(side='left', pady=5)
        
        entryfields = Frame(frame)
        entryfields.pack(side='right', pady=5)
        
        Label(self.dimensions, text="lenght:", font=NORMAL_FONT).pack(pady=3)
        Label(self.dimensions, text="wide:", font=NORMAL_FONT).pack(pady=4)
        Label(self.dimensions, text="height:", font=NORMAL_FONT).pack(pady=4)
        self.volume=Label(self.dimensions, textvariable = self.v).pack()
        
    
        rl = Entry(entryfields, textvariable = self.lenght)
        rl.pack(pady=6)
        rw = Entry(entryfields, textvariable = self.wide)
        rw .pack(pady=6)
        rh = Entry(entryfields, textvariable = self.height)
        rh.pack(pady=6)
        #fa = Entry(entryfields)
        #fa.pack(pady=6)

    
        button3 = ttk.Button(self, text="calculate")
        button3.pack()
        button3.bind("<Button-1>", self.calculate)
        
        button2 = ttk.Button(self, text="Page 2", 
                            command=lambda: controller.show_frame(PageTwo))
        button2.pack()
        
        button1 = ttk.Button(self, text="Start Page", 
                            command=lambda: controller.show_frame(StartPage))
        button1.pack()
        
        
        
    def calculate(self, carryout):
        try:
            l = float(self.lenght.get())
            b = float(self.wide.get())
            h = float(self.height.get())
            p = l*b*h
            self.v.set("volume: % .2f m³" % p)
            return p
        
        except ValueError:
            tk.messagebox.showinfo('No valid input.','Please enter only numbers!',icon = 'warning')
     

class PageTwo(PageOne, tk.Frame):
    
    def __init__(self, parent, controller):
       
        tk.Frame.__init__(self, parent)
        
        frame = Frame(self)
        frame.pack(pady=20)
        
        
        self.s = StringVar()
        
        self.dimension = Frame(frame)
        self.dimension.pack(side='left', pady=5)
        
       
        label = tk.Label(self, text="Page 2", font=LARGE_FONT)
        label.pack(pady = 10, padx = 10)
        
        pasvar = tk.Label(self.dimension, textvariable = self.s)
        pasvar.pack()

        
        button1 = ttk.Button(self, text="Start Page", 
                            command=lambda: controller.show_frame(StartPage)).pack()

        button2 = ttk.Button(self, text="Page 1", 
                            command=lambda: controller.show_frame(PageOne)).pack()
        
        button3 = ttk.Button(self, text="pasvariable")
        button3.pack()
        button3.bind("<Button-1>", self.pasvariable)

    def pasvariable(self, var):
        m = PageOne.__init__(self,parent,controller)
        self.s.set("volume: % .2f m³" % m)
        return m



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



app = reverberationTime()
app.mainloop()
I get this error:

runfile('E:/Python/Akustik/Akustik/Nachhallzeit_Rechner.py', wdir='E:/Python/Akustik/Akustik')
Exception in Tkinter callback
Traceback (most recent call last):
  File "E:\Anaconda\Anacon\lib\tkinter\__init__.py", line 1705, in __call__
    return self.func(*args)
  File "E:/Python/Akustik/Akustik/Nachhallzeit_Rechner.py", line 156, in pasvariable
    m = PageOne.__init__(self,parent,controller)
NameError: name 'parent' is not defined
If your going to have numerous pages, instead of passing variables back and forth utilize classes and use inheritance to your advantage. Whatever data you need to pass between classes make super Pages class that is inherited by all page classes. Put any data that needs to be passed among all pages in there. If you want each page to have their own variable then make it a inheritance attribute, if you want it to have a single value among all sub classes, then have it a class attribute instead.


I think this is what you are trying to do? Because PAgeOne and PageTwo are both subclasses of Pages class, they both can modify and read the data of the super class attribute. This also stops any passing variables that clogs up code anywhere you pass to and from variables.
import tkinter as tk
from tkinter import ttk
from tkinter import *
LARGE_FONT = ("Verdana", 12)
 
 
     
class reverberationTime(tk.Tk):
     
     
    def __init__(self,*args,**kwargs):
     
        
        tk.Tk.__init__(self, *args, **kwargs)
         
        tk.Tk.wm_title(self, "reverberation time")
        #tk.Tk.iconbitmap(self,"C:/Users/PC/Desktop/Icons/speaker.ico")
         
        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, PageThree):
     
            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 Pages:
    p = 0
         
class StartPage(tk.Frame, Pages):
     
    def __init__(self, parent, controller):
        tk.Frame.__init__(self,parent)
        label = tk.Label(self, text="reverberation time", font=LARGE_FONT)
        label.pack(pady = 10, padx = 10)
         
        button = ttk.Button(self, text="welcome!", 
                            command=lambda: controller.show_frame(PageOne)).pack()

         
class PageOne(tk.Frame, Pages):
 
     
    def __init__(self, parent, controller):
         
     
        tk.Frame.__init__(self, parent)
        NORMAL_FONT=("Arial",11)
         
        title = tk.Label(self, text="Please enter the dimensions", font=LARGE_FONT)
        title.pack(pady = 10, padx = 10)
        
        frame = Frame(self)
        frame.pack(pady=20)
         
        self.lenght = StringVar()
        self.wide = StringVar()
        self.height = StringVar()
        self.v = StringVar()
         
        self.dimensions = Frame(frame)
        self.dimensions.pack(side='left', pady=5)
         
        entryfields = Frame(frame)
        entryfields.pack(side='right', pady=5)
         
        Label(self.dimensions, text="lenght:", font=NORMAL_FONT).pack(pady=3)
        Label(self.dimensions, text="wide:", font=NORMAL_FONT).pack(pady=4)
        Label(self.dimensions, text="height:", font=NORMAL_FONT).pack(pady=4)
        self.volume=Label(self.dimensions, textvariable = self.v).pack()
         
     
        rl = Entry(entryfields, textvariable = self.lenght)
        rl.pack(pady=6)
        rw = Entry(entryfields, textvariable = self.wide)
        rw .pack(pady=6)
        rh = Entry(entryfields, textvariable = self.height)
        rh.pack(pady=6)
        #fa = Entry(entryfields)
        #fa.pack(pady=6)
 
     
        button3 = ttk.Button(self, text="calculate")
        button3.pack()
        button3.bind("<Button-1>", self.calculate)
         
        button2 = ttk.Button(self, text="Page 2", 
                            command=lambda: controller.show_frame(PageTwo))
        button2.pack()
         
        button1 = ttk.Button(self, text="Start Page", 
                            command=lambda: controller.show_frame(StartPage))
        button1.pack()
         
         
         
    def calculate(self, carryout):
        try:
            l = float(self.lenght.get())
            b = float(self.wide.get())
            h = float(self.height.get())
            p = l*b*h
            self.v.set("volume: % .2f m³" % p)
            #return p
            Pages.p = p
            
         
        except ValueError:
            tk.messagebox.showinfo('No valid input.','Please enter only numbers!',icon = 'warning')
      
 
class PageTwo(tk.Frame, Pages):
     
    def __init__(self, parent, controller):
        
        tk.Frame.__init__(self, parent)
         
        frame = Frame(self)
        frame.pack(pady=20)
         
         
        self.s = StringVar()
         
        self.dimension = Frame(frame)
        self.dimension.pack(side='left', pady=5)
         
        
        label = tk.Label(self, text="Page 2", font=LARGE_FONT)
        label.pack(pady = 10, padx = 10)
         
        pasvar = tk.Label(self.dimension, textvariable = self.s)
        pasvar.pack()
 
         
        button1 = ttk.Button(self, text="Start Page", 
                            command=lambda: controller.show_frame(StartPage)).pack()
 
        button2 = ttk.Button(self, text="Page 1", 
                            command=lambda: controller.show_frame(PageOne)).pack()
         
        button3 = ttk.Button(self, text="pasvariable")
        button3.pack()
        button3.bind("<Button-1>", self.pasvariable)
 
    def pasvariable(self, var):
        #m = PageOne.__init__(self,parent,controller)
        self.s.set("volume: % .2f m³" % Pages.p)
 
 
 
class PageThree(tk.Frame, Pages):
     
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
     
       
 
 
 
app = reverberationTime()
app.mainloop()
You are right, this is exactly what I want to do!! thank you very much...