访问需要Tkinter中的类参数的不同类中的变量

时间:2018-04-13 21:19:28

标签: python tkinter

我正在研究一个Tkinter项目,因为它越来越大我开始使用类。在最终弄清楚如何使用多个类作为框架之后,现在我再次陷入了一些新问题,无法找到解决方案。

我需要访问类中的变量,该变量是在另一个类中定义的。但是在定义它的原始位置,该类需要参数。所以除非我将一个参数与其类一起使用,否则我无法调用此变量。但由于我这里唯一的目的是访问此变量甚至修改它,如何在不影响Tkinter小部件的情况下执行此操作。

这个Tkinter计划的组织也是一个很好的方法吗?我见过人们做得与众不同。不确定这个组织是否合适。

import tkinter as tk

#Main Window
class MainProgram():
    def __init__(self):
        self.win = tk.Tk()   
        self.win.title("Class Tester")
        self.win.resizable("True", "True")     
        self.frame_1 = FirstFrame(self.win)        
        self.frame_2 = SecondFrame(self.win)       

 #First Frame       
class FirstFrame():
    def __init__(self, parent):
        self.parent =parent
        self.frame1 = tk.LabelFrame(self.parent, text="Frame 1")
        self.frame1.pack()  
        self.show_widgets()      
    def show_widgets(self):
        self.label1 = tk.Label(self.frame1, text="Hi 1")
        self.label1.grid(column=0, row=0)
    def a_fuction(self):
        self.var1 = 5 #Need to access this var from a different class
#Second Frame        
class SecondFrame():
    def __init__(self, parent):
        self.parent = parent
        self.frame2 = tk.LabelFrame(self.parent, text="Frame 2")
        self.frame2.pack()
        self.show_widgets()
        self.b_fuction()
    def show_widgets(self):
        self.label2 = tk.Label(self.frame2, text="Hi 2")
        self.label2.grid(column=1, row=0)
    def b_fuction(self):
        self.var2 = FirstFrame().var1 
        #Tryig to access but requires class argument "parent".
        print(self.var2)



if __name__ == "__main__":
    app = MainProgram().win
    app.mainloop()

4 个答案:

答案 0 :(得分:0)

要从另一个实例访问一个实例中的属性,您只需要引用该另一个实例。

可以说最好的解决方案是让你的MainProgram充当控制者。也就是说,MainProgram知道其他帧,其他帧可以在需要时请求它作为参考。

首先,更改MainProgram以将自身传递给其他框架:

class MainProgram():
    def __init__(self):
        ...     
        self.frame_1 = FirstFrame(self, self.win)        
        self.frame_2 = SecondFrame(self, self.win)
        ...

class FirstFrame():
    def __init__(self, main, parent):
        self.main = main
        ...

class SecondFrame():
    def __init__(self, main, parent):
        self.main = main
        ...

接下来,您可以使用self.main获取另一帧的实例:

class SecondFrame():
    ...  
    def b_fuction(self):
        first_frame = self.main.frame_1
        self.var2 = first_frame.var

答案 1 :(得分:0)

每当你发现自己问“我如何访问...”时,答案通常是你已经有权访问它,但是把它扔掉了,所以修复就是不这样做。

在这种情况下:您想要的SecondFrame实例已存在,MainProgram实例知道它,但FirstFrame无法返回其父实例。它有一个parent成员,但这只是win的{​​{1}}成员,而不是MainProgram成员。

你将两种设计混合在一起。您的组织就像创建继承MainProgram的子类的典型tkinter惯用法一样,但您已经将其改编为创建独立的类,只需 Frame而不是一个..你的设计很好 - 事实上,它可以说比通常的OO更好(它是模型 - 视图设计的一半) - 但它意味着你需要跟踪父对象,不只是它的窗口(即模型,而不是视图)。

所以,你可以这样做:

Frame

答案 2 :(得分:0)

这是我在查看回复之前找到的解决方案。虽然我在类中定义变量,而不是使用self.var,但我使用的是ClassXXX.var。这样我就可以通过将其称为ClassXXX.var来访问其他类中的变量。

import tkinter as tk

#Main Window
class MainProgram():
    def __init__(self):
        self.win = tk.Tk()   
        self.win.title("Class Tester")
        self.win.resizable("True", "True")     
        self.frame_1 = FirstFrame(self.win)        
        self.frame_2 = SecondFrame(self.win)       


#First Frame       
class FirstFrame():

    def __init__(self, parent):

        self.parent =parent
        self.frame1 = tk.LabelFrame(self.parent, text="Frame 1")
        self.frame1.pack()  
        self.show_widgets()      
    def show_widgets(self):
        FirstFrame.var1 = 5 #Variable is declared in this style instead
        self.label1 = tk.Label(self.frame1, text="Hi 1")
        self.label1.grid(column=0, row=0)

#Second Frame        
class SecondFrame():
    def __init__(self, parent):
        self.parent = parent
        self.frame2 = tk.LabelFrame(self.parent, text="Frame 2")
        self.frame2.pack()
        self.show_widgets()
        self.b_fuction()
    def show_widgets(self):
        self.label2 = tk.Label(self.frame2, text="Hi 2")
        self.label2.grid(column=1, row=0)
    def b_fuction(self):
        self.var2 = FirstFrame.var1
        print(self.var2)



if __name__ == "__main__":
    app = MainProgram().win
    app.mainloop()

答案 3 :(得分:-1)

我相信你已经在代码中解决了这个问题而没有注意到,因为你已经传递了父类的实例,你可以通过该实例引用类之间的变量。

#Main Window
class MainProgram():
    def __init__(self):
        self.frame_1 = FirstFrame(self)        
        self.frame_2 = SecondFrame(self)       

 #First Frame       
class FirstFrame():
    def __init__(self, parent):
        self.parent =parent

    def a_fuction(self):
        self.parent.var1 = 5 

#Second Frame        
class SecondFrame():
    def __init__(self, parent):
        self.parent =parent
    def b_fuction(self):
        self.var2 = self.parent.var1

以下是需要做些什么的一个小例子。