Interclass变量引用

时间:2014-05-23 08:54:02

标签: python-3.x tkinter

这是我用来生成一种填充值的一些代码的示例,这些代码将在更改字段时自行更新。我已经被困了几天阅读并尝试从另一个类的方法中的一个类调用变量。我这样做的原因是让代码更加模块化和可读性,因为我最终会有大约30个部分。此外,作为一项规则,我通常不会在命名对象时使用数字。

from tkinter import *
from tkinter import ttk

class Application(ttk.Frame):
    def __init__(self, master=None):
        ttk.Frame.__init__(self, master)
        self.grid()
        Frame1()
        Frame2()
        Frame3()

class Frame1(ttk.Frame):
    def __init__(self, master=None):
        ttk.Frame.__init__(self, master)
        self.grid()
        ttk.Label(self, text="Frame1").grid()
        self.var1 = IntVar()
        self.SetVar1()
        ttk.Label(self, textvariable=self.var1).grid()

    def SetVar1(self):
        self.var1.set(2)

class Frame2(ttk.Frame):
    def __init__(self, master=None):
        ttk.Frame.__init__(self, master)
        self.grid()
        ttk.Label(self, text="Frame2").grid()
        self.var2 = IntVar()
        self.SetVar2()
        ttk.Label(self, textvariable=self.var2).grid()

    def SetVar2(self):
        self.var2.set(3)

class Frame3(ttk.Frame):
    def __init__(self, master=None):
        ttk.Frame.__init__(self, master)
        self.grid()
        ttk.Label(self, text="Frame3").grid()
        self.var3 = IntVar()
        self.SetVar3()
        ttk.Label(self, textvariable=self.var3).grid()

    def SetVar3(self):
        self.var3.set(Frame1.var1.get() + Frame2.var2.get())

app = Application()
app.master.title("Window")
app.mainloop()

在代码底部,

发生错误
def SetVar3(self):
    self.var3.set(Frame1.var1.get() + Frame2.var2.get())

我无法超越它。显然我不能以这种方式调用var1。它会导致以下错误。

AttributeError: type object 'Frame1' has no attribute 'var1'

正确执行后,代码应类似于:

Frame1
  2
Frame2
  3
Frame3
  5

那么,我错过了什么?

(刚才有下面的评论,但是它们已经消失了,这真的有助于讨论这个话题。我会在睡了一觉后再回过头来看看。也许那时下面的评论会神奇地再次出现,我可以回复反过来。

一条评论提到创建Frame1和Frame2的新实例以在Frame3中调用,但除非这些新实例共享来自Application中已初始化的实例的值,否则它将无济于事。另一条评论提到我的代码中有错误,但没有详细说明。

当我回复每个评论时,每个评论都消失了,我收到了警告,要编辑我原来的帖子。我是否错过了评论意见?)

1 个答案:

答案 0 :(得分:1)

Frame1Frame2都是类,而不是实例。这就是您在该行代码中遇到错误的原因(var1var2是实例变量,而不是类变量。)

要完成这项工作,您需要将引用传递给Frame1Frame2个实例(或者可能是var1var2变量的实例)Frame3

尝试将Application更改为:

class Application(ttk.Frame):
    def __init__(self, master=None):
        ttk.Frame.__init__(self, master)
        self.grid()
        f1 = Frame1() # save frames to local variables, so we can reference them
        f2 = Frame2()
        f3 = Frame3(f1, f2) # pass previous frames as args!

然后让Frame3使用参数(此处我只是直接从SetVar3将其传递给__init__,但您可以将它们保存为self上的属性,如果你想要的):

class Frame3(ttk.Frame):
    def __init__(self, f1, f2, master=None):  # take other frames as parameters
        ttk.Frame.__init__(self, master)
        self.grid()
        ttk.Label(self, text="Frame3").grid()
        self.var3 = IntVar()
        self.SetVar3(f1, f2)     # pass frames on
        ttk.Label(self, textvariable=self.var3).grid()

    def SetVar3(self, f1, f2):   # take frames as parameters here too
        self.var3.set(f1.var1.get() + f2.var2.get()) # use the references

显然,在实际代码中,逻辑可能需要不同。想一想框架之间的逻辑关系是什么,让它们在适当时传递(并且可能保存)彼此的引用。