如何使用for循环创建按钮

时间:2016-12-06 13:32:41

标签: python-3.x loops user-interface tkinter

它在tkinter中。最后一行添加x = len(FRAME_LIST)"按钮"进入下拉菜单。问题是它们都引用了同一帧(FRAME_LIST中的最后一帧)。如何使每个Button从FRAME_LIST引用不同的帧?

    for F in FRAME_LIST:
        frame = ChallengePage(mainframe,self, F)
        self.frames[F] = frame
        frame.grid(row = 0, column = 0, sticky = "nsew")
        subMenu1.add_command(label = F.id, command = lambda: self.show_frames(F))

编辑: 所以更确切地说,当我遇到这个问题我认为没问题,问题是我需要声明一个局部变量,所以我尝试了这个:

        A = F
        subMenu1.add_command(label = F.id, command = lambda: self.show_frames(A))

但即使A在循环中声明为INS并且在每个循环中重新声明,它仍然无效,它仍会产生相同的结果。

我现在穿过链接:https://docs.python.org/3/faq/programming.html#why-do-lambdas-defined-in-a-loop-with-different-values-all-return-the-same-result

显示解决方案:

        subMenu1.add_command(label = F.id, command = lambda A = F: self.show_frames(A))

哪种方式神奇地起作用,但我不明白为什么它与我当地的A有任何不同。

1 个答案:

答案 0 :(得分:0)

在循环中使用lambda时,这是一个常见问题。我通常使用partial代替:

from functools import partial

for F in FRAME_LIST:
    frame = ChallengePage(mainframe, self, F)
    self.frames[F] = frame
    frame.grid(row=0, column=0, sticky="nsew")
    subMenu1.add_command(label=F.id, command=partial(self.show_frames, F))

因为:closures

总结一下:循环中的lambda将记住变量(F)的名称,但不记得循环的每次迭代时它指向的值。当您单击按钮并触发命令时,名称F指向for循环迭代中的最后一个值,因此将传递给您的lambda。另一方面,Partials知道F在每次迭代时指向的对象,并跟踪它,以便使用适当的参数调用self.show_frames()