I have a project with a problem that I recreated in this small code
from tkinter import *
top = Tk()
mb= Menubutton ( top, text="condiments", relief=RAISED )
mb.grid()
mb.menu = Menu ( mb, tearoff = 0 )
mb["menu"] = mb.menu
for dressing in ['ketchup','mayo']:
mb.menu.add_command( label=dressing , command=lambda:print(dressing))
mb.pack()
top.mainloop()
so in this example, no matter what I choose in the menu - it prints "mayo" because the last dressing in the loop is mayo and the loop created the menu.
Does anyone have an idea how to fix this issue?
Try this
from tkinter import *
top = Tk()
mb=Menubutton(top,text="condiments",relief=RAISED)
mb.grid()
mb.menu=Menu(mb,tearoff=0)
mb["menu"]=mb.menu
for dressing in ['ketchup','mayo']:
mb.menu.add_command(label=dressing,command=lambda d=dressing:print(d))
mb.pack()
top.mainloop()
Adding d=dressing
stores the current value of dressing
in a variable d
which is sent to the print
statement.
it prints "mayo" because the last dressing in the loop is mayo
That's the precise reason, when the lambda
function was executed later, it took the last assigned value of dressing
which in your case happens to be mayo
and not the value that it had at the time of assignment.