Tkinter按钮颜色修改问题求助:点击按钮仅最后一个按钮变色
解决Tkinter按钮点击仅修改最后一个按钮背景色的问题
哈哈,这个坑我刚学Tkinter的时候也踩过!问题出在你循环里用的lambda表达式上——这是个典型的闭包延迟绑定问题。
简单说:当你写lambda : AskColor(c)的时候,lambda并没有把当前循环的c值存下来,它只是记住了“我要引用变量c”。等你实际点击按钮的时候,循环早就跑完了,c的值已经变成了列表最后一个元素的索引(也就是3),所以不管点哪个按钮,都会触发修改最后一个按钮的颜色。
两种快速修复方案
方案1:给lambda加默认参数捕获当前索引
这是最常用的解决办法,给lambda添加一个默认参数c=c,这样就能把循环当前的c值“固定”在lambda里,而不是引用后续会变化的变量:
import tkinter as tk from tkinter import colorchooser tabStyle = tk.Tk() tabStyle['background'] = "black" texts = ['Background', 'Foreground', 'Cursor' , '...'] labels = [] buttons = [] def AskColor(c): color = colorchooser.askcolor()[1] if color: # 加个判断,防止用户取消选色时返回None导致报错 buttons[c]['background'] = color for c, s in enumerate(texts): labels.append(tk.Label(tabStyle, text=s, fg="white", bg="black")) # 关键修改:用默认参数c=c捕获当前循环的索引 buttons.append(tk.Button(tabStyle, width=5, bg="white", command=lambda c=c : AskColor(c))) # 简化循环写法,更清晰 for idx, label in enumerate(labels): label.grid(column=0, row=idx, sticky="W") for idx, button in enumerate(buttons): button.grid(column=1, row=idx, padx=2) tabStyle.mainloop()
方案2:用functools.partial绑定参数
如果你觉得lambda的写法有点绕,也可以用functools.partial来帮你绑定函数参数,效果完全一样:
import tkinter as tk from tkinter import colorchooser from functools import partial # 导入partial tabStyle = tk.Tk() tabStyle['background'] = "black" texts = ['Background', 'Foreground', 'Cursor' , '...'] labels = [] buttons = [] def AskColor(c): color = colorchooser.askcolor()[1] if color: buttons[c]['background'] = color for c, s in enumerate(texts): labels.append(tk.Label(tabStyle, text=s, fg="white", bg="black")) # 用partial把当前的c绑定到AskColor的参数上 buttons.append(tk.Button(tabStyle, width=5, bg="white", command=partial(AskColor, c))) for idx, label in enumerate(labels): label.grid(column=0, row=idx, sticky="W") for idx, button in enumerate(buttons): button.grid(column=1, row=idx, padx=2) tabStyle.mainloop()
两种方案都能解决问题,选你觉得顺手的就行~现在点击每个按钮,就能正确修改对应按钮的背景色啦!
内容的提问来源于stack exchange,提问作者LousAjo
相关产品推荐
相关产品推荐

