请注意,我的问题与此相反:Creating functions in a loop因为我有很多按钮和一个功能,而没有很多功能。
我从for
循环中创建10个带编号的按钮,然后尝试将每个按钮绑定到一个将打印按钮编号的函数;参见下面的代码:
import tkinter as tk
class Window(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
# creating buttons and adding them to dictionary
self.buttons = {}
for number in range(1, 11):
self.buttons.update({'button' + str(number): tk.Button(self, height=1, width=4, bg="grey", text=number)})
# example of a pair in the dictionary: 'button2': <Tkinter.Button instance at 0x101f9ce18>
""" bind all the buttons to callback, each button is
named something like 'button3',so I take the number off
the end of its name and feed that as an argument to Callback"""
for button in self.buttons:
self.buttons[button].bind('<Button-1>', lambda event: self.Callback(event, button[6:]))
self.buttons[button].pack(side='left')
def Callback(self, event, num):
print(num)
所有按钮出现在窗口上都没问题,但是当我单击其中的任何一个时,控制台都会打印“ 10
”,而不是按钮的编号。看来该功能只是记住它给出的最后一个参数。
答案 0 :(得分:3)
首先让我们更正您的代码以提供所需的答案。
import tkinter as tk
class Window(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.buttons = {}
for number in range(1, 11):
self.buttons.update({'button' + str(number): tk.Button(self, height=1, width=4, bg="grey", text=number)})
for button in self.buttons:
self.buttons[button].bind('<Button-1>', lambda event, num=button[6:]: self.Callback(event, num))
self.buttons[button].pack(side='left') #\____________/
def Callback(self, event, num):
print(num)
Window().mainloop()
说明:
诀窍在于lambda函数的工作方式。
在编写lambda event: self.Callback(event, button[6:])
时,该实例没有得到 button[6:]
的值并将其存储。相反,它会创建一个 closure ,这有点像对自身的注释:“ 我应该在我当时寻找变量button(迭代器)的值是什么称为”。
现在,当循环结束并且每个小部件都已准备好并进行设置时,您调用它,它将在那个时候寻找 button 的值,这当然是迭代(此处为button10
)。
num=button[6:]
使函数在定义lambda时存储计数器的当前值(此处为 button ),而不是等待查找的值按钮。
积分:BrenBarn
只需添加,您就可以使用command
小部件的Button
属性以更少的代码来完成当前的工作。这是一个例子。
import tkinter as tk
class Window(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
for number in range(1, 11):
tk.Button(self, height=1, width=4, bg="grey", text=number, command=lambda num=number: self.Callback(num)).pack(side='left')
def Callback(self, num):
print(num)
Window().mainloop()