2020-10-19:补充lambda修改的具体依据
首先动态创建按钮,操作比较简单,也很多类似范例
import tkinter as tk
import tkinter.messagebox as msg
cb_list = ['cmd1', 'cmd2', 'cmd3']
win = tk.Tk()
for inx, cmd in enumerate(cb_list):
tk.Button(win, width=10, height=1, text=cmd).grid(row=0, column=inx)
win.mainloop()
然后,尝试给按钮绑定事件。
由于按钮是动态创建,那么绑定的事件,就需要通过参数来区分,是哪一个按钮点击触发的。
同样找到一些范例,大多类似以下lambda
的写法
import tkinter as tk
import tkinter.messagebox as msg
def cbClicked(cbname):
print(cbname)
msg.showinfo('您点击了', cbname)
cb_list = ['cmd1', 'cmd2', 'cmd3']
win = tk.Tk()
for inx, cbname in enumerate(cb_list):
tk.Button(win, width=10, height=1, text=cbname, command = lambda:cbClicked(cbname))\
.grid(row=0, column=inx)
win.mainloop()
但实际运行结果发现,传递的参数都是 ‘cmd3’,并没有实现上叙目的。
再次查看相关文档,修改lambda
。
command = lambda arg=cbname:cbClicked(arg)
最终实现,动态创建按钮,并绑定事件且动态传参。效果如图:
2020-10-19:补充lambda修改的具体依据
为了说明和演示,以下图代码为例:
首先lambda是匿名函数,lambda:x**2
等效于
那么,funcs.append(lambda:x**2)
和command = lambda:cbClicked(cbname))
都只是引用了这个函数, 并没有执行它
。
引用的是lambda:x**2
而不是lambda:0**2, lambda:1**2, lambda:2**2
当我们执行它,也就是结尾的print语句,此时循环已经结束,x=2
,为了更好的说明这一点,看下图代码运行结果
按文中的方法修改为lambda y=x: y ** 2
,此时的x只是参数y的初始值,在定义函数的时候,已经取了x的值,最终分别引用的是
lambda y=0: y ** 2
lambda y=1: y ** 2
lambda y=2: y ** 2
3个函数
回复a280571634
评论,实现点击按钮变色
import tkinter as tk
import tkinter.messagebox as msg
def cbClicked(cbname):
for cb in cb_group:
cb_group[cb]["cbobj"]["fg"] = "red" if cb==cbname else "black"
# msg.showinfo('您点击了', cbname)
cb_group = {
"cb1": {'cbname': "按钮1", 'cbobj': None},
"cb2": {'cbname': "按钮2", 'cbobj': None},
"cb3": {'cbname': "按钮3", 'cbobj': None}
}
win = tk.Tk()
for inx, cb in enumerate(cb_group):
b = tk.Button(win, width=10, height=1, text=cb_group[cb]["cbname"])
b["command"] = lambda arg=cb: cbClicked(arg)
b.grid(row=0, column=inx)
cb_group[cb]["cbobj"] = b
win.mainloop()