【问题标题】:Checkbuttons and buttons: using lambda检查按钮和按钮:使用 lambda
【发布时间】:2015-07-02 10:49:03
【问题描述】:

我正在尝试根据列表制作多个复选框,但是看起来我搞砸了按钮的 命令调用可变方面

我的代码是:

class Example(Frame):

def __init__(self, parent):
    Frame.__init__(self, parent)

    self.parent = parent
    self.initUI()

def initUI(self):

    self.courses = ["CSE 4444", "CSE 4343"]
    self.vars = []

    self.parent.title("Homework Helper")

    self.course_buttons()

    self.pack(fill=BOTH, expand=1)

def course_buttons(self):
    x = 0
    y = 0

    for i in range(0, len(self.courses)):
        self.vars.append(IntVar())
        cb = Checkbutton(self, text=self.courses[i],
                         variable=self.vars[i],
                         command=lambda: self.onClick(i))
        cb.select()
        cb.grid(column=x, row=y)
        y = y+1

def onClick(self, place):

    print place
    if self.vars[place].get() == 1:
        print self.courses[place]

目前的测试是在复选框打开时在控制台上打印课程,但它仅适用于第二个按钮,即“CSE 4343”按钮。当我与按钮“CSE 4444”交互时,没有打印任何内容。

此外,无论我是单击“CSE 4343”按钮还是“CSE 4444”按钮,onClick 的“位置”值始终为 1。

【问题讨论】:

  • 究竟是什么不起作用?与观察到的行为相比,预期的行为是什么?有任何错误信息吗?
  • @TigerhawkT3 我在编辑中提到了这些对不起。
  • 由于lambda closure scoping,请尝试lambda i=i: self.onClick(i)

标签: python user-interface tkinter


【解决方案1】:

当你创建一个lambda 函数时,它的引用只会在函数被调用时解析为值。因此,如果您在循环中使用可变值(代码中的 i)创建 lambda 函数,则每个函数都会获得相同的 i - 最后一个可用的函数。

但是,当您使用默认参数定义函数时,该引用会在函数定义后立即解析。通过将这样的参数添加到您的 lambda 函数中,您可以确保它们获得您想要的值。

lambda i=i: self.onClick(i)

如果您想进行更多研究,这称为词法 scoping 或闭包。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-28
    • 1970-01-01
    • 2021-08-14
    • 1970-01-01
    • 2020-06-28
    • 2012-01-24
    • 2019-05-29
    • 2019-01-15
    相关资源
    最近更新 更多