I am new to python and learning to make some basic tkinter apps in windows. I have defined a menubar and add one menu to it. Then added multiple labels to this menu, but when I click any button in the menu, all the commands are ran, I am wondering how to run only the clicked menu?
MWE
(Problem: whichever menu I click, it runs all the menu labels)
import tkinter as tk
from tkinter import ttk,messagebox
def show_child_win(win,text=''):
win_child = tk.Toplevel(win)
var_l1 = tk.StringVar()
l1 = tk.Label(win_child,textvariable=var_l1)
l1.grid(row=0, column=0)
var_l1.set(text)
win_child.after(3*1000,lambda: win_child.destroy())
win = tk.Tk()
menubar = tk.Menu(win)
menu = tk.Menu(menubar, tearoff=0)
menubar.add_cascade(label="Scripts", menu=menu)
dict_label_func = {
'function_01': lambda win: show_child_win(win,text='function_01'),
'function_02': lambda win: show_child_win(win,text='function_02'),
'last_function': lambda win: show_child_win(win,text='last_function')
}
for label, func in dict_label_func.items():
menu.add_command(label=label,command = lambda x=win: func(x))
win.config(menu=menubar)
win.mainloop()
How to make the code run only the function it supposed to do?
CodePudding user response:
The problem lies in your lambda
functions, I think you are not able to understand the difference between func
and func()
.
abcd
basically represents a function which can be called.
abcd()
is actually calling that abcd
function.
lambda
behaves like abcd
, so do not need to do abcd: abcd()
.
Here is the corrected part of the code:
dict_label_func = {
'function_01': lambda: show_child_win(win, text='function_01'),
'function_02': lambda: show_child_win(win, text='function_02'),
'last_function': lambda: show_child_win(win, text='last_function')
}
for label, func in dict_label_func.items():
menu.add_command(label=label,command = func)
Please refer this tutorial on functions and lambda.
CodePudding user response:
As per comments of @Henry,
Following code worked for me:
command = lambda f=func: f(win)