Tkinter按钮绑定函数异常求助:点击添加确认触发所有editUser
问题分析与解决
核心错误1:按钮command参数直接执行函数
你在创建用户按钮时写了:
newUser = Button(main, text = users[len(users)-1].n, command = editUser(len(users)-1))
这里的editUser(len(users)-1)会立即执行函数,而不是把函数作为点击回调。所以点击添加用户的confirm时,所有editUser都会被触发,而用户按钮点击时已经没有可执行的回调逻辑了。
修复方法:用lambda绑定参数
把command改成lambda表达式,让函数在按钮点击时才执行:
newUser = Button(main, text=users[-1].n, command=lambda x=len(users)-1: editUser(x))
这里用x=len(users)-1把当前索引值固定下来,避免lambda引用后续变化的变量。
核心错误2:用Tk()创建子窗口
你在addUser和editUser里用Tk()创建新窗口,这会创建多个Tk主实例,导致tkinter内部状态混乱,引发各种奇怪的交互问题。
修复方法:改用Toplevel()创建子窗口
把addUserWindow = Tk()改成addUserWindow = Toplevel(main),editUserWindow = Tk()改成editUserWindow = Toplevel(main)。
其他优化点
- 用
users[-1]代替users[len(users)-1],代码更简洁; - 编辑窗口的输入框默认填充当前用户的名字和分数,提升操作体验;
- 编辑分数时转成整数类型,避免后续出现字符串类型的分数值。
修复后的完整代码
from tkinter import * from tkinter import ttk users = [] class User: def __init__(self, name, points): self.n = name self.p = points main = Tk() main.title("Main") def addUser(): global users addUserWindow = Toplevel(main) addUserWindow.title("Add User") def confirm(): global users users.append(User(nameentry.get(), 0)) newUser = Button(main, text=users[-1].n, command=lambda x=len(users)-1: editUser(x)) newUserPoints = Label(main, text=users[-1].p) newUser.grid(column=0, row=len(users)+1) newUserPoints.grid(column=1, row=len(users)+1) addUserWindow.destroy() name = Label(addUserWindow, text="Name: ") newname = StringVar() nameentry = Entry(addUserWindow, width=8, textvariable=newname) upd = Button(addUserWindow, text="add", command=confirm) name.grid(column=0, row=0) nameentry.grid(column=1, row=0) upd.grid(column=1, row=1) def editUser(x): editUserWindow = Toplevel(main) editUserWindow.title("Edit User") frame = Frame(editUserWindow) frame.grid(column=0, row=0) user = Label(frame, text=users[x].n) points = Label(frame, text=users[x].p) userentry = Entry(frame, textvariable=StringVar(value=users[x].n)) pointsentry = Entry(frame, textvariable=StringVar(value=str(users[x].p))) def confirm(): global users users[x].n = userentry.get() users[x].p = int(pointsentry.get()) editUserWindow.destroy() confirmButton = Button(frame, text="confirm", command=confirm) user.grid(column=0, row=0) points.grid(column=0, row=1) userentry.grid(column=1, row=0) pointsentry.grid(column=1, row=1) confirmButton.grid(column=2, row=1) addUserButton = Button(main, text='add user', command=addUser) addUserButton.grid(column=1, row=1) main.mainloop()
内容的提问来源于stack exchange,提问作者Christian Hodges
相关产品推荐
相关产品推荐

