【问题标题】:How do I make buttons with a for-loop [duplicate]如何使用for循环制作按钮[重复]
【发布时间】:2016-12-06 13:32:41
【问题描述】:

它在 tkinter 中。最后一行将 x = len(FRAME_LIST) "Buttons" 添加到下拉菜单中。问题是它们都引用同一个框架(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 在循环内声明并在每个循环中重新声明,它也不起作用,它仍然产生相同的结果。

我现在看到了这个链接: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 有任何不同。

【问题讨论】:

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


    【解决方案1】:

    这是在循环中使用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()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-02-03
      • 2015-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-17
      • 1970-01-01
      相关资源
      最近更新 更多