错误解释 - 'statInter'对象没有属性'tk'

3
我正在尝试使用Python创建一个简单的计时器,并打算使用类来构建用户界面。我想使用这些类来初始化用户界面。然后在主体的主要文本中,我想使用".grid"和".configure"方法添加属性。但是当我尝试这样做时,会出现错误:"statInter"对象没有"tk"属性。

我是编程的初学者,但如果我正确理解了这个错误,它是因为".grid"和其他Button方法没有被我的statInter(即静态界面)类继承所导致的。这是正确的吗?我该如何解决这个错误?我尝试继承Button类和Tk类的属性,但在后一种情况下,我会得到无限递归的错误,即超过最大递归深度。
谢谢您的帮助。
#This is a simple timer version

from tkinter import *

window = Tk()
window.title('Tea timer')
window.minsize(300,100)
window.resizable(0,0)

class statInter(Button,Entry):

    def __init__(self, posx, posy):
        self.posx = posx  # So the variables inside the class are defined broadly
        self.posy = posy

    def button(self):
        Button(window).grid(row=self.posx, column=self.posy)

    def field(self):
        Entry(window, width=5)

sth = statInter(1,2)
sth.grid(row=1, column = 2)

window.mainloop()
2个回答

4
问题在于您派生的StatInter类(根据CamelCasing类名建议,按照PEP 8 - Style Guide for Python Code)没有初始化其基类,这通常在Python中不会隐式发生(如在C++中发生)。
为了从StatInter.__init__()方法内部执行此操作,您需要知道将包含它的parent小部件(除顶级窗口外,所有小部件都包含在层次结构中),因此需要向派生类的构造函数传递额外的参数,以便可以将其传递到每个基类构造函数中。
您还没有遇到另一个问题,但很快可能会遇到。 为了避免它,在button()field()中显式调用基类方法时,还需要明确传递self
from tkinter import *

window = Tk()
window.title('Tea timer')
window.minsize(300,100)
window.resizable(0,0)

class StatInter(Button, Entry):

    def __init__(self, parent, posx, posy):  # Added parent argument
        Button.__init__(self, parent)  # Explicit call to base class
        Entry.__init__(self, parent)  # Explicit call to base class
        self.posx = posx  # So the variables inside the class are defined broadly
        self.posy = posy

    def button(self):
        Button.grid(self, row=self.posx, column=self.posy)  # Add self

    def field(self):
        Entry.config(self, width=5)  # Add self

sth = StatInter(window, 1, 2)  # Add parent argument to call
sth.grid(row=1, column=2)

window.mainloop()

这是一个很好的答案,尽管我怀疑 OP 要么想从 ButtonEntry 继承,要么使用组合创建 ButtonEntry,但不会两者都要。 - Bryan Oakley
@Bryan:谢谢。你说得对,“is-a”和“has-a”的问题当然存在。我试图回答得足够好,以解决立即的问题,让OP能够继续开发——同时指出在Python中进行多重继承时可能会遇到一些潜在的未来问题,这也是我认为他们可能想要实现的。 - martineau

1
你得到这个错误的原因是因为你从你继承的类中没有调用任何一个构造函数(要么是 Button,要么是 Entry)。
如果你将你的 __init__ 改成如下:
def __init__(self, posx, posy):
    Button.__init__(self)
    self.posx = posx  # So the variables inside the class are defined broadly
    self.posy = posy

那么你以前遇到的错误就不会再出现了,而且会弹出一个小窗口。在新的__init__中,我们显式地调用了Button的构造函数。

与Java和其他一些语言不同,默认情况下不会调用super构造函数。我假设每个继承自其他tkinter类的类都必须有一个tk字段。通过调用您选择的父构造函数,将创建此字段。如果您不调用父构造函数,则这将不是已建立的字段,您将得到所描述的错误('statInter'对象没有属性'tk')。

希望对您有所帮助!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接