我正在写一个简单的gui来改变显示器的亮度,但是我遇到了一个问题。
def start_ui(self):
root = Tk()
root.wm_title("Set brightness")
col = 0
for k, v in self.monitors.iteritems():
print k
Scale(root, variable = DoubleVar(), command = lambda(r): self.change_brightness(k, r)).grid(row=0, column=col)
labelVar = StringVar()
label = Label(root, textvariable=labelVar).grid(row=1, column=col)
labelVar.set(k)
col += 1
root.mainloop()
这是我开始我的UI,我的self的地方。监视器的字典是这样的:{'LVDS1': '1.0', 'VGA1': '1.0'}.
循环的输出如预期的那样是"LVDS1, VGA1",然而,当我移动滑块并调用回调时,总是传递k的最后一个值,在这种情况下是"VGA1",无论我移动哪个滑块。
是什么原因导致的?
问题是你的lambda
函数-它想用k
和r
调用change_brightness
,但k
在被调用之前没有解决。因此,它正在使用全局变量k
在调用函数时保存的值。如果在for
循环外有一行写着k = 'SomeNonsenseValue'
,那么这个值将被传递给lambda函数。
试试这个:
for k, v in self.monitors.iteritems():
def createLambda(k):
return lambda(r): self.change_brightness(k, r)
Scale(root, variable = DoubleVar(), command = createLambda(k)).grid(row=0, column=col)
创建一个闭包,允许lambda函数在创建函数时保留k
的值。