动态创建带命令的按钮时所有按钮命令参数均绑定列表最后一项如何解决
Tkinter循环生成按钮传参异常解决方案
问题根因
该问题由Python闭包的延迟绑定特性导致:lambda表达式内部引用的board变量不会在循环迭代时立即保存当前值,按钮点击触发lambda执行时,循环已遍历完成,board固定为boards列表的最后一个元素,所有按钮点击都会传入同一个参数。
修复方案
方案1:lambda默认参数绑定(最简写法)
利用Python函数默认参数会在定义阶段求值的特性,将每次迭代的board值绑定为lambda的默认参数,即可实现每次循环对应独立参数:
def BoardSelect(): Clear() boards = getBoards() for board in boards: Button(root, **config, bg="dark gray", text=board, command=lambda b=board:PresetSelect(b)).pack(fill="x", pady=2) Button(root, **config, bg="dark gray", text="All", command=lambda:ImageViewer("all")).pack(fill="x", pady=2) Button(root, **config, bg="red", text="Back", command=lambda:mainMenu()).pack(fill="x", pady=2)
方案2:索引遍历绑定
如果需要通过range按索引访问列表元素,同理将当前索引绑定为lambda默认参数即可:
def BoardSelect(): Clear() boards = getBoards() for i in range(len(boards)): Button(root, **config, bg="dark gray", text=boards[i], command=lambda idx=i:PresetSelect(boards[idx])).pack(fill="x", pady=2) Button(root, **config, bg="dark gray", text="All", command=lambda:ImageViewer("all")).pack(fill="x", pady=2) Button(root, **config, bg="red", text="Back", command=lambda:mainMenu()).pack(fill="x", pady=2)
内容的提问来源于stack exchange,提问作者Clay9870
相关产品推荐
相关产品推荐

