如何解决Tkinter中TypeError: addtrans() missing 1 required positional argument: 'self'错误
解决
TypeError: addtrans() missing 1 required positional argument: 'self'的问题 嘿,这个错误我之前也踩过坑!原因其实很直白:你的addtrans是一个类的实例方法(它需要self参数来指向类的实例),但你给按钮的command参数直接传了addtrans,没有把它和类的实例绑定起来——所以点击按钮调用时,Python不知道该把什么作为self传进去,自然就报错了。
下面给你几个靠谱的解决办法,你可以根据自己的代码结构选:
方法1:如果按钮是类的一部分,用self.addtrans作为command
如果你的按钮是在类的初始化方法(比如__init__)里创建的,那直接把command设为self.addtrans就行——Python会自动把当前类实例作为self参数传递给方法:
class TransactionApp: def __init__(self, root): self.root = root # 这里用self.addtrans绑定实例 self.add_btn = Button(root, text="Add New Transaction", command=self.addtrans) self.add_btn.pack() def addtrans(self): # 把全局的root换成self.root,代码更规范 newWin = Toplevel(self.root) width = 600 height = 400 screenwidth = self.root.winfo_screenwidth() screenheight = self.root.winfo_screenheight() alignstr = '%dx%d+%d+%d' % (width, height, (screenwidth - width)/2, (screenheight - height)/2) newWin.geometry(alignstr) newWin.resizable(width=False, height=False) self.lbl1 = Label(newWin, text="Enter amount in Euros :", fg='red') self.lbl1.place(x=150 , y=50) self.euros = Entry(newWin, width=20) self.euros.place(x=300, y=50) self.lbl2 = Label(newWin, text="CATEGORY :", fg='green') self.lbl2.place(x=150 , y=80) self.cat_entry = Entry(newWin, width=20) self.cat_entry.place(x=299, y=80) self.place_entry = Label(newWin, text=" ENTER NAME OF PLACE :") self.place_entry.place(x=140, y=120) self.txtfld2 = Entry(newWin, width=20) self.txtfld2.place(x=299, y=120) # 注意:如果submit也是类方法,要改成self.submit self.submit_btn=Button(newWin, text="SUBMIT RECORD TO DATABASE", command=self.submit) self.submit_btn.place(x=280, y=160)
方法2:按钮在类外部?用functools.partial绑定实例
如果你的按钮是在类外面创建的,但addtrans是类的方法,那可以用functools.partial把类实例和方法绑定在一起,这样调用时就会自动传self了:
from functools import partial # 先创建类的实例 app = TransactionApp(root) # 用partial绑定app实例到addtrans方法 add_btn = Button(root, text="Add Transaction", command=partial(app.addtrans)) add_btn.pack()
方法3:把addtrans改成普通函数(不推荐,除非不需要类属性)
如果你的代码其实不需要用到类的属性(比如self.euros这些控件引用),那可以把addtrans改成不带self的普通函数,这样直接传addtrans给command就不会报错了,但这样你就没法用self来存储控件,需要调整代码去掉所有self.前缀:
def addtrans(): newWin = Toplevel(root) width = 600 height = 400 screenwidth = root.winfo_screenwidth() screenheight = root.winfo_screenheight() alignstr = '%dx%d+%d+%d' % (width, height, (screenwidth - width)/2, (screenheight - height)/2) newWin.geometry(alignstr) newWin.resizable(width=False, height=False) lbl1 = Label(newWin, text="Enter amount in Euros :", fg='red') lbl1.place(x=150 , y=50) euros = Entry(newWin, width=20) euros.place(x=300, y=50) lbl2 = Label(newWin, text="CATEGORY :", fg='green') lbl2.place(x=150 , y=80) cat_entry = Entry(newWin, width=20) cat_entry.place(x=299, y=80) place_entry = Label(newWin, text=" ENTER NAME OF PLACE :") place_entry.place(x=140, y=120) txtfld2 = Entry(newWin, width=20) txtfld2.place(x=299, y=120) submit_btn=Button(newWin, text="SUBMIT RECORD TO DATABASE", command=submit) submit_btn.place(x=280, y=160)
最后提个小建议:代码里最好别用全局的root,如果是在类里,把root存成实例属性(比如self.root)会更规范,也能避免全局变量带来的潜在问题。另外你的submit函数如果也是类的方法,记得也要用self.submit作为按钮的command哦!
内容的提问来源于stack exchange,提问作者Danielkelly
相关产品推荐
相关产品推荐

