首页 > 解决方案 > OptionMenu add_command 需要直接命令吗?

问题描述

我被困住了

我正在使用 refresh() 函数更改 OptionMenu 的内容,它在 A 情况下工作正常,但在 B 情况下我将其更改为回调时,OptionMenu 停止工作。单击一个选项不再选择它。

知道是什么原因吗?

案例一:

import tkinter as tk
root = tk.Tk()
cvar = tk.StringVar(root)
cvar.set("-")
optionlist = ('one', 'two', 'three')

def refresh(contentlist):
    optionmenu['menu'].delete(0, 'end')

    for content in contentlist:
        optionmenu['menu'].add_command(label=content, command=tk._setit(cvar, content))

def doNothing():
    return

optionmenu = tk.OptionMenu(root, cvar, *optionlist, command=doNothing)
optionmenu.pack()

refresh(optionlist)

root.mainloop()

案例B:

def contentcallback(var, name):
    tk._setit(var, name)

def refresh(contentlist):
    optionmenu['menu'].delete(0, 'end')

    for content in contentlist:
        optionmenu['menu'].add_command(label=content, command=contentcallback(cvar, content))

标签: pythonpython-3.xtkinteroptionmenutkinter.optionmenu

解决方案


@stovfl 发表的评论给了我另一个解决方案

tk._setit 有一个我不知道的回调函数。使用该回调我可以做到:

def contentcallback(var, name):
    #Whatever I need to do

def refresh(contentlist):
    optionmenu['menu'].delete(0, 'end')

    for content in contentlist:
        optionmenu['menu'].add_command(label=content, command=tk._setit(var, name, lambda cv=cvar, con=content: contentcallback(cv, con)))

编辑:@BryanOakley 给出了为什么我的原始解决方案充满漏洞的链接

tk._setit 方法返回一个使其工作所需的对象。原来的 contentcallback 只调用了方法而不是它背后的方法。这使得设置有点奇怪:

def contentcallback(var, name, func):
    #Whatever I need to do
    func()

def refresh(contentlist):
    optionmenu['menu'].delete(0, 'end')

    for content in contentlist:
        optionmenu['menu'].add_command(label=content, command=lambda cv=cvar, co=content, func=tk._setit(cvar, content): contentcallback(cvar, co, func))

推荐阅读