import tkinter as tk from tkinter.scrolledtext import ScrolledText ### This program demonstrates a failure in using the lambda function with a loop variable. ### The expected behaviour is that each command is build using the current value of the loop variable ### but it seems that all commands ar build at the end of the function calling the loop. ### Each command is build using the last value of the loop variable, if the variable is changed ### sfter the end of the loop within the function this value is used instead entries = ['alpha', 'beta', 'gamma', 'delta'] # Menu entries to be used def initGUI(): """ GUI initialisation """ global root, menu_ok, menu_nok, OUT root = tk.Tk() root.title("Menu demo") menubar = tk.Menu(root) menu_ok = tk.Menu(menubar, tearoff=0) # Prepare menu for working entries menubar.add_cascade(label="Working", menu=menu_ok) menu_nok = tk.Menu(menubar, tearoff=0) # Prepare menu for not working entries menubar.add_cascade(label="Failure", menu=menu_nok) root.config(menu=menubar) # Add the menubar OUT = ScrolledText(root, width=40, height = 16) # Prepare output area OUT.pack() return def build_menu(): """ Build up the menus """ for name in entries: menu_nok.insert_command(tk.END, label=name, command=lambda:cmd(name)) # create menu entry directly from loop # using 'name' as menu entry label # using 'name' as option for command setmen(name) # create menu entry using function name="senseless" # should not have any effect # but all commands build inside the loop # will use this value # if not set the last value of loop # is used for all commands return def setmen(menu): """ add menu entry """ menu_ok.insert_command(tk.END, label=menu, command=lambda:cmd(menu)) # create menu entry identically as in the loop return def cmd(param): """ print name ehere it is called from """ OUT.insert(tk.INSERT, "called from %s\n" %param) # Display output return if __name__ == '__main__': initGUI() build_menu() # simulates calling configparser root.mainloop()