繁体   English   中英

将许多按钮绑定到函数,将每个按钮的名称作为参数传递

[英]Binding many buttons to a function, passing each button's name as an argument

请注意,我的问题与此相反: 在循环创建函数 ,因为我有许多按钮和一个函数,而不是很多函数。

我从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 ”,而不是按钮的编号。 似乎该函数只记住它给出的最后一个参数。

首先,让我们更正您的代码,以提供所需的答案。

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:]的值并存储它。 相反,它会产生一个闭包 ,这有点像对自己的说法“ 我应该在我被称为时应该查找变量按钮(迭代器)的值 。“

现在当循环结束并且每个小部件都准备好并设置好,并且你调用它时,它将在那时查找按钮的值,这当然是迭代的最后一个值(这里是button10 )。

num=button[6:]使函数在定义lambda时存储计数器的当前值(此处为按钮 ),而不是等待稍后查找按钮的值。

致谢: BrenBarn


只是添加,您可以使用Button小部件的command属性以更少的代码执行您正在执行的操作。 这是一个例子。

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()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM