嵌套的tkinter命令功能如何工作? [英] How nested tkinter command functions work?

查看:147
本文介绍了嵌套的tkinter命令功能如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

代码示例来自此答案.

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

When click a Button with a command function (and this command function itself will call another menu command function), like the code example, what would happen? When clicking Refresh menu why has lambda command show() not been activated?

为清楚起见,我对原始代码进行了如下更改:

For clarity, I made some changes about the original code as below:

  • 注释Button().invoke
  • 添加一些print()信息
  • 并更改/添加一些counting variables
  • comment out Button().invoke
  • add some print() information
  • and change/add some 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), label_choice, refresh_count, '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, id(menu), 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")

推荐答案

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

When click a Button with a command function (and this command function itself will call another menu command function), like the code example, what would happen?

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

It's unclear what you're asking here. Tkinter has no control over this, the commands will run in the order that they are called.

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

When clicking Refresh menu why has lambda command show() not been activated?

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

lambda doesn't call a function, it defines a new anonymous function. In this example, it creates a new function and assigns it to a menu item. The created function won't run until the user selects that item from the menu.

让我们看一下这段代码:

Let's look at this code:

 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.它创建了一个新的匿名函数,它将调用当选择了菜单项.

The statement being printed is incorrect. The code before it does not call show. It creates a new anonymous function which will call show when the menu item is selected.

这篇关于嵌套的tkinter命令功能如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆