嵌套的tkinter命令功能如何工作?

代码示例来自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")
wensu521 回答:嵌套的tkinter命令功能如何工作?

  

当单击带有命令功能的按钮(此命令功能本身将调用另一个菜单命令功能)时,如代码示例所示,会发生什么?

目前您不清楚在问什么。 Tkinter无法对此进行控制,这些命令将按照被调用的顺序运行。

  

单击“刷新”菜单时,为什么未激活lambda命令show()?

lambda不调用函数,它定义了一个新的匿名函数。在此示例中,它将创建一个新功能并将其分配给菜单项。在用户从菜单中选择该项目之前,创建的功能将无法运行。


让我们看一下这段代码:

 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 {}"...

正在打印的语句不正确。 not 之前的代码不会调用show。它创建了一个新的匿名函数,当选择菜单项时,它将调用show

本文链接:https://www.f2er.com/3121905.html

大家都在问