代码示例来自this answer。
当单击带有命令功能的按钮(此命令功能本身将调用另一个菜单命令功能)时,如代码示例所示,会发生什么?单击Refresh menu
时为什么未激活lambda command
show()
?
为清楚起见,我对原始代码进行了如下更改:
- 评论
Button().invoke
- 添加一些
print()
信息 - 并更改/添加一些
counting variables
# Using lambda keyword and refresh function to create a dynamic menu.
# Set python script name as `tk_dynamic.py`
import tkinter as tk
choice_count = 0
refresh_count = 0
invoke_count = 1
def show(label,count):
""" Show your choice """
global label_choice,choice_count
choice_count += 1
new_label = 'Choice is: ' + label
menubar.entryconfigure(label_choice,label=new_label) # change menu text
label_choice = new_label # update menu label to find it next time
print("\nUpdate root menubar(id {})'s label as `{}`\n\
when adding command #{} to cascade menu(id {}) at refresh count {} in `show()`"\
.format(id(menubar),label_choice,count,id(menu),refresh_count))
choice.set(label)
print("Reset `variable choice` {} {} as {} in show() when adding command #{}\n"\
.format(choice_count,'times' if choice_count > 1 else 'time',label,count))
def refresh():
""" Refresh menu contents """
global label_choice,label_cascade,refresh_count,choice_count
refresh_count += 1
if label_cascade[0] == 'one':
label_cascade = ['four','five','six','seven']
else:
label_cascade = ['one','two','three']
choice.set('')
choice_count = 0 # reset choice changing count
menu.delete(0,'end') # delete previous contents of the menu
menubar.entryconfigure(label_choice,label=const_str) # change menu text
label_choice = const_str # update menu label to find it next time
print('\nUpdate root menubar(id {}) and set label as `{}` {} {} in `refresh()`'\
.format(id(menubar),'times' if refresh_count > 1 else 'time'))
command_count = 1
for l in label_cascade:
menu.add_command(label=l,command=lambda label=l,count=command_count: show(label,count))
print("Add command #{} to cascade menu(id {}) by calling show() at refresh count {}"\
.format(command_count,refresh_count))
print("Choice change count is {} when adding command #{} at refresh count {}"\
.format(choice_count,command_count,refresh_count))
command_count += 1
root = tk.Tk()
# Set some variables
choice = tk.StringVar()
const_str = 'Choice'
label_choice = const_str
label_cascade = ['dummy']
# Create some widgets
menubar = tk.Menu(root)
root.configure(menu=menubar)
# menu = tk.Menu(menubar,tearoff=False)
menu = tk.Menu()
print('Before adding cascade menu(id {}) to root menubar(id {})'.format(id(menu),id(menubar)))
menubar.add_cascade(label=label_choice,menu=menu)
b = tk.Button(root,text='Refresh menu',command=refresh)
b.pack()
# b.invoke()
# print("Invoke {} {} button command"\
# .format(invoke_count,'times' if invoke_count > 1 else 'time'))
# invoke_count += 1
print("Updating textvariable by changing variable choice {} {}"\
.format(choice_count,'times' if choice_count > 1 else 'time'))
tk.Label(root,textvariable=choice).pack()
root.geometry("300x100")
root.mainloop()
print("This statement is after `mainloop()` and should print on closing window")