【问题标题】:How do I fix the following error in Tkinter on __init__ function?如何修复 Tkinter 中 __init__ 函数的以下错误?
【发布时间】:2023-02-09 23:19:23
【问题描述】:

我是 Tkinter 的新手,正在构建一个用于与 ML 程序交互的微型 UI。这是我用于创建的 UI 窗口的代码:

from tkinter import *
from tkinter import ttk

class UI:

    def __init__(self, root):

        root.title("Retirement Savings Estimator")

        mainframe = ttk.Frame(root, padding="3 3 12 12")
        mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
        root.columnconfigure(0, weight=1)
        root.rowconfigure(0, weight=1)

        self.age = IntVar()
        self.age = ttk.Entry(mainframe, width=7, textvariable=self.age)
        self.age.grid(column=2, row=1, sticky=(W, E))
        ttk.Label(mainframe, text ="Enter your age: ").grid(column=1, row=1, sticky=(W, E))

        self.yearly_salary = StringVar()
        self.yearly_salary = ttk.Entry(mainframe, width=7, textvariable=self.yearly_salary)
        self.yearly_salary.grid(column=2, row=2, sticky=(W, E))
        ttk.Label(mainframe, text="Enter your gross yearly wages: ").grid(column=1, row=2, sticky=(W, E))

        for child in mainframe.winfo_children():
            child.grid_configure(padx=5, pady=5)

        ttk.Label(mainframe, text="Press the Calculate button to get your estimate: ").grid(column=1, row=3, sticky=(W, E))
        action = ttk.Button(mainframe, text="Calculate", default = "active", command = UI).grid(column=2, row=3, sticky=(W, E))
        self.age.focus()
        root.bind('<Return>', action)
        
    def predict_savings(*args, root):
        try:  
            user_age = int(self.age.get())
            yr_salary = float(self.yearly_salary.get())
            estimate = regr.predict(user_age, yr_salary)
            ttk.Label(mainframe, text="Your Estimated Amount to Save For Retirement: " + estimate).grid(column=1, row=4, sticky=(W, E))
        except ValueError:
            pass
        
root = Tk()   
UI(root)
root.mainloop()

这是我在 UI 窗口中按下“计算”按钮时收到的错误消息:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\jesst\anaconda3\lib\tkinter\__init__.py", line 1892, in __call__
    return self.func(*args)
TypeError: __init__() missing 1 required positional argument: 'root'

我已经尝试将“root”添加到 predict_savings() 函数以查看这是否解决了问题,并生成了一个不同的错误。我不确定还能尝试什么。任何想法都会很棒。

【问题讨论】:

  • 你想为command=UI做什么“计算”按钮?单击按钮时创建按钮所属类的实例没有意义。

标签: python-3.x tkinter


【解决方案1】:

错误是这行代码:

action = ttk.Button(mainframe, text="Calculate", default = "active", command = UI).grid(column=2, row=3, sticky=(W, E))

您要求 tkinter 在单击按钮时创建 UI 的新实例。但是,UI被定义为需要root作为参数之一。当您单击按钮时,没有传递任何参数,这就是您收到错误的原因。

由于按钮存在于UI内,而predict_savings位于UI内,正确的解决方案是让按钮调用self.predict_savings。另外,predict_savings 不需要参数。它不使用参数,所以我认为没有理由需要它们。但是,它确实像任何其他类方法一样需要 self 参数。

    ...
    action = ttk.Button(..., command = self.predict_savings)...
    ...

def predict_savings(self):
    ...



【讨论】:

  • user_age = int(self.age.get()) ^^^^ NameError: name 'self' is not defined
  • @toyotaSupra:我的回答在这里解决:“此外,predict_savings ... 确实需要 self 参数,就像任何其他类方法一样。”
【解决方案2】:

下面的行创建类 UI 的新实例。

action = ttk.Button(mainframe, text="Calculate", default = "active", command = UI).grid(column=2, row=3, sticky=(W, E))

当我们按下“计算”按钮时,我们希望看到估计值,而不是新窗口。估计函数是self.predict_savings,所以我们应该用command = lambda: self.predict_savings()替换command = UI

action = ttk.Button(mainframe, text="Calculate", default = "active", command = lambda: self.predict_savings()).grid(column=2, row=3, sticky=(W, E))

【讨论】:

  • user_age = int(self.age.get()) ^^^^ NameError: name 'self' is not defined
  • 按钮在这里不需要使用lambda,可以是command=self.predict_savings
【解决方案3】:

作为@Bryan Oakley,尝试使用 self 解释实例化类。

我不明白这是什么estimate = regr.predictregr.predict 已定义。我不得不删除它。

你的错误太多了。

  • self添加到self.mainframe到每个小部件。
  • predict_savings参数中添加自己。不需要这个*args, root。还需要处理陷阱try/ except
  • 将 f=string 用于 Label

代码修改:

from tkinter import *
from tkinter import ttk

class UI:
    def __init__(self, root):

        root.title("Retirement Savings Estimator")

        self.mainframe = ttk.Frame(root, padding="3 3 12 12")
        self.mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
        root.columnconfigure(0, weight=1)
        root.rowconfigure(0, weight=1)

        self.age = IntVar()
        self.age = ttk.Entry(self.mainframe, width=7, textvariable=self.age)
        self.age.grid(column=2, row=1, sticky=(W, E))
        ttk.Label(self.mainframe, text ="Enter your age: ").grid(column=1, row=1, sticky=(W, E))

        self.yearly_salary = StringVar()
        self.yearly_salary = ttk.Entry(self.mainframe, width=7, textvariable=self.yearly_salary)
        self.yearly_salary.grid(column=2, row=2, sticky=(W, E))
        ttk.Label(self.mainframe, text="Enter your gross yearly wages: ").grid(column=1, row=2, sticky=(W, E))

        for child in self.mainframe.winfo_children():
            child.grid_configure(padx=5, pady=5)

        ttk.Label(self.mainframe, text="Press the Calculate button to get your estimate: ").grid(column=1, row=3, sticky=(W, E))
        action = ttk.Button(self.mainframe, text="Calculate", default = "active", command =self.predict_savings).grid(column=2, row=3, sticky=(W, E))
        self.age.focus()
        root.bind('<Return>', action)
        
    def predict_savings(self):
        #try:  
        user_age = int(self.age.get())
        yr_salary = float(self.yearly_salary.get())
        estimate = (user_age, yr_salary)
        ttk.Label(self.mainframe, text=f"Your Estimated Amount to Save For Retirement:  {estimate}").grid(column=1, row=4, sticky=(W, E))
        #except ValueError:
            #pass
        
root = Tk()   
app = UI(root)
root.mainloop()

截屏:

计算后截图:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-07
    • 2017-10-11
    • 1970-01-01
    • 1970-01-01
    • 2019-12-08
    • 2019-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多