Python Forum
How can I pass a variable to another class, especially in this situation?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How can I pass a variable to another class, especially in this situation?
#1
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
Reply
#2
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()
Recommended Tutorials:
Reply
#3
You are right, this is exactly what I want to do!! thank you very much...
Reply
#4
Dear Sr,

Thank you very much for sharing your knowledge. I was looking for this answer for 2 months. It seems that no one, but you, knows how to get a variable and use everywhere. A lot of people talk but dont say anything.

best
PKanda
Reply
#5
Any variable declared in the module scope (global) is global to all modules that import that module.

blackboard.py
"""Global variables for my application"""
a = 0
mymodule.py
import blackboard

def print_a():
    print("othermodule", blackboard.a)

print_a()
Output:
othermodule 0
test_blackboard.py
import blackboard

def print_a():
    print("module", blackboard.a)

def set_a(a):
    blackboard.a = a

class A():
    def print(self):
        print("A", blackboard.a)

    def set(self, a):
        blackboard.a = a

blackboard.a = 3.14

print_a()
set_a(7)
print_a()
a = A()
a.print()
a.set(11)
print_a()

import mymodule

print_a()
blackboard.a = 711
mymodule.print_a()
Output:
module 3.14 module 7 A 7 module 11 othermodule 11 module 11 othermodule 711
Class variables are global in the same way. A class is kind of like a mini-module. It has a global namespace and variables defined in this namespace are called "class variables". These class variables are shared by all instances of the class and can even be seen outside of the class by using the class_name.class_variable_name.
class A():
    a = 1234

    @classmethod
    def global_set(cls, a):
        cls.a = a

    def print(self):
        print("A", self.a)

    def set(self, a):
        self.a = a

a = A()
print('From outside', A.a)
a.print()

print('A.global_set(2)')
A.global_set(2)
print('From outside', A.a)
a.print()

print('a.set(2)')
a.set(4)
print('From outside', A.a)
a.print()
Output:
From outside 1234 A 1234 A.global_set(2) From outside 2 A 2 a.set(2) From outside 2 A 4
I'm sorry you spent 2 months looking for this information. I've have had a few questions that were difficult to find answers for. Not because the question was hard, but because I didn't know how to ask the question. Your particular question is made even more difficult by the "global" scope specifier hiding information about what it means to be global. What you really needed to research is "scope" or "namespace".
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  pass a variable between tkinter and toplevel windows janeik 10 2,294 Jan-24-2024, 06:44 AM
Last Post: Liliana
  [Tkinter] Take the variable of a cursor class delcencen 2 1,184 Feb-13-2023, 05:19 AM
Last Post: deanhystad
  Getting a variable from one class to another class menator01 6 3,133 Apr-26-2020, 04:36 PM
Last Post: Larz60+
  Updating a variable within a class MC2020 2 2,575 Apr-17-2020, 11:31 AM
Last Post: MC2020
  [Tkinter] Update variable between class/frame edwin6938 6 4,539 Nov-22-2019, 08:13 AM
Last Post: edwin6938

Forum Jump:

User Panel Messages

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