Tkinter 选项菜单小部件添加命令 lambda 不产生预期的命令
Tkinter option menu widget add command lambda does not produce expected command
我正在尝试创建一个 window,它有一个基于文件选择对话框填充的选项菜单。我能够使选项菜单包含基于先前选择的文件的所有选项。但是,无论用户选择什么选项,该变量都包含从所选文件中读取的最后一个选项。
如果有人能向我解释为什么会这样,我会很高兴。因此,我在下面包含了一个最小示例:
from Tkinter import *
Tk()
class App():
chunks = ['A','B','C'] # These are read from a file in the actual program
testVariable = StringVar()
def __init__(self,master):
def initSummary():
self.dataButton["menu"].delete(0, 'end')
for i in self.chunks:
print i # To demonstrate what's in there
self.dataButton["menu"].add_command(label=i, command = lambda: self.testVariable.set(i))
top = self.top = Toplevel()
top.protocol("WM_DELETE_WINDOW", lambda: close(self))
self.sumButton = Button(top, text="Test", width=25, command=lambda: initSummary())
self.sumButton.grid(row=0, column=0, sticky=W)
self.dataButton = OptionMenu(top, self.testVariable, "Stuff")
self.dataButton.grid(row=0, column=1, sticky=W)
# Call the main app
root = Tk()
app = App(root)
root.mainloop()
此代码将在选项菜单上显示 C
,无论用户选择了什么,而代码中的 print
会产生预期的 A
、B
和 C
。如果 print
也显示了 3 次 C
我会理解,但是打印的内容和 GUI 中显示的内容不匹配让我失望。
我通过添加如下代码所示的中间函数解决了 for 循环中 lambda 的问题(感谢@j_4321)。
from Tkinter import *
class App():
chunks = ['A','B','C']
def __init__(self,master):
self.testVariable = StringVar()
def refresh():
# Prints what's in the variable
print self.testVariable.get()
def testFunc(x):
return lambda: self.testVariable.set(x)
def initSummary():
self.dataButton["menu"].delete(0, 'end')
for i in self.chunks:
self.dataButton["menu"].add_command(label=i, command = testFunc(i))
top = self.top = Toplevel()
self.sumButton = Button(top, text="Test", width=25, command=lambda: initSummary())
self.sumButton.grid(row=0, column=0, sticky=W)
self.dataButton = OptionMenu(top, self.testVariable, "Stuff")
self.dataButton.grid(row=0, column=1, sticky=W)
self.testButton = Button(top, text="Variable", width=25, command = lambda: refresh())
self.testButton.grid(row=1, column=0, sticky=W)
# Call the main app
root = Tk()
app = App(root)
root.mainloop()
如果这不是解决此问题的 'correct' 方法,请发表评论。
我正在尝试创建一个 window,它有一个基于文件选择对话框填充的选项菜单。我能够使选项菜单包含基于先前选择的文件的所有选项。但是,无论用户选择什么选项,该变量都包含从所选文件中读取的最后一个选项。
如果有人能向我解释为什么会这样,我会很高兴。因此,我在下面包含了一个最小示例:
from Tkinter import *
Tk()
class App():
chunks = ['A','B','C'] # These are read from a file in the actual program
testVariable = StringVar()
def __init__(self,master):
def initSummary():
self.dataButton["menu"].delete(0, 'end')
for i in self.chunks:
print i # To demonstrate what's in there
self.dataButton["menu"].add_command(label=i, command = lambda: self.testVariable.set(i))
top = self.top = Toplevel()
top.protocol("WM_DELETE_WINDOW", lambda: close(self))
self.sumButton = Button(top, text="Test", width=25, command=lambda: initSummary())
self.sumButton.grid(row=0, column=0, sticky=W)
self.dataButton = OptionMenu(top, self.testVariable, "Stuff")
self.dataButton.grid(row=0, column=1, sticky=W)
# Call the main app
root = Tk()
app = App(root)
root.mainloop()
此代码将在选项菜单上显示 C
,无论用户选择了什么,而代码中的 print
会产生预期的 A
、B
和 C
。如果 print
也显示了 3 次 C
我会理解,但是打印的内容和 GUI 中显示的内容不匹配让我失望。
我通过添加如下代码所示的中间函数解决了 for 循环中 lambda 的问题(感谢@j_4321)。
from Tkinter import *
class App():
chunks = ['A','B','C']
def __init__(self,master):
self.testVariable = StringVar()
def refresh():
# Prints what's in the variable
print self.testVariable.get()
def testFunc(x):
return lambda: self.testVariable.set(x)
def initSummary():
self.dataButton["menu"].delete(0, 'end')
for i in self.chunks:
self.dataButton["menu"].add_command(label=i, command = testFunc(i))
top = self.top = Toplevel()
self.sumButton = Button(top, text="Test", width=25, command=lambda: initSummary())
self.sumButton.grid(row=0, column=0, sticky=W)
self.dataButton = OptionMenu(top, self.testVariable, "Stuff")
self.dataButton.grid(row=0, column=1, sticky=W)
self.testButton = Button(top, text="Variable", width=25, command = lambda: refresh())
self.testButton.grid(row=1, column=0, sticky=W)
# Call the main app
root = Tk()
app = App(root)
root.mainloop()
如果这不是解决此问题的 'correct' 方法,请发表评论。