Python:在循环中创建Tkinter按钮时,如何在lambda函数中传递不同的参数?

时间:2018-08-27 22:11:38

标签: python tkinter

这是我当前的脚本:

import tkinter as tk

class Soundboard(tk.Frame):
    def __init__(self, sounds, master=None):
        super().__init__(master)

        self.sounds = sounds

        self.pack()    
        self.create_button_loop()

    def create_button_loop(self):
        self.buttons = {}
        for name, sound in self.sounds.items():
            self.buttons[name] = tk.Button(self, text=name, command = lambda :play_sound(sound))
            self.buttons[name].pack(side='top')    
        #sound = 10



def play_sound(a_sound):
    print(a_sound)


#MAIN SCRIPT
if __name__ == '__main__':

    sounds = {'a':1, 'b':2, 'c':3}
    board = Soundboard(sounds)

有一个类Soundboard和一个函数play_sound,底部是脚本部分。声音是一种使用{name : sound}模式的字典,当前sound只是一个数字,而函数play_sound只是打印出它所调用的内容。

我一直遇到的问题是create_button_loop的{​​{1}}方法。在循环中,对于每个Soundboard / name组合,在字典sound中创建一个按钮,其中self.buttons是按钮的文本,name被传递到sound(lambda语句)。

我想发生的事情是创建按钮时通过lambda语句传递的play_soundsound,而不是按下按钮时的sound,所以{ {1}}应打印sound的原始值。实际发生的情况是,稍后play_sound重新分配(通过循环的下一次迭代)时,按下按钮时,sound会播放sound的当前值。

在此示例中,创建了3个按钮,“ a”,“ b”和“ c”。当按下“ a”时,将打印“ 3”(play_sound的最新重新分配是在for循环的最后一次迭代中,因此sound / sound = name / sound,而不是创建按钮“ a”时的“ 1”。

如何c更改时避免在lambda语句中传递的3值更改?我更喜欢这样的迭代方法,而不是为每个sound组合编写不同的回调函数,但是如果那是最好的方法,请告诉我。预先谢谢你!

1 个答案:

答案 0 :(得分:1)

使用Intent代替lambda。

functools.partial