这是我用来生成一种填充值的一些代码的示例,这些代码将在更改字段时自行更新。我已经被困了几天阅读并尝试从另一个类的方法中的一个类调用变量。我这样做的原因是让代码更加模块化和可读性,因为我最终会有大约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中已初始化的实例的值,否则它将无济于事。另一条评论提到我的代码中有错误,但没有详细说明。
当我回复每个评论时,每个评论都消失了,我收到了警告,要编辑我原来的帖子。我是否错过了评论意见?)
答案 0 :(得分:1)
Frame1
和Frame2
都是类,而不是实例。这就是您在该行代码中遇到错误的原因(var1
和var2
是实例变量,而不是类变量。)
要完成这项工作,您需要将引用传递给Frame1
和Frame2
个实例(或者可能是var1
和var2
变量的实例)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
显然,在实际代码中,逻辑可能需要不同。想一想框架之间的逻辑关系是什么,让它们在适当时传递(并且可能保存)彼此的引用。