python - tkinter 在 for 循环中创建按钮传递命令参数

标签 python tkinter

我正在尝试在 for 循环内的 tkinter 中创建按钮。并且每个循环都将 i 计数值作为命令值中的参数传递出去。因此,当从 command 值调用该函数时,我可以知道按下了哪个按钮并采取相应的行动。

问题是,假设长度为 3,它将创建 3 个按钮,标题为 Game 1Game 3 但是当任何一个按钮被按下时,打印的值总是2,最后一次迭代。所以看起来按钮是作为单独的实体制作的,但是命令参数中的 i 值似乎都是一样的。代码如下:

def createGameURLs(self):
    self.button = []
    for i in range(3):
        self.button.append(Button(self, text='Game '+str(i+1),
                                  command=lambda: self.open_this(i)))
        self.button[i].grid(column=4, row=i+1, sticky=W)

def open_this(self, myNum):
    print(myNum)

有没有办法在每次迭代时获取当前的 i 值以坚持使用该特定按钮?


这个问题可以认为是Creating functions in a loop的特例.还有What do lambda function closures capture? ,以获得更多技术概述。

另见How to pass arguments to a Button command in Tkinter?对于将参数传递给 Button 回调的一般问题。

最佳答案

将您的 lambda 更改为 lambda i=i: self.open_this(i)

这可能看起来很神奇,但这就是正在发生的事情。当您使用该 lambda 定义函数时, open_this 调用不会在您定义函数时获取变量 i 的值。相反,它创建了一个闭包,这有点像给自己的一个注释,说“我应该查找变量 i 的值是什么在我被调用时”。当然,该函数是在循环结束后调用的,所以那时 i 将永远等于循环中的最后一个值。

使用 i=i 技巧会使您的函数在定义 lambda 时存储 i 的当前值,而不是等待稍后查找 i 的值。

关于python - tkinter 在 for 循环中创建按钮传递命令参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10865116/

相关文章:

python - 我的程序使用了大量内存,我该怎么办?

python - 使窗口不会相互重叠

python - 如何根据按钮点击无条件重新运行python程序?

python - Django 模型 : root node appears as child in unsaved nodes

python - 自动更新GET请求python

python - Selenium 显式等待错误地接受 EC.visibility_of_element_located xpath 元素

python - Tkinter 回调

python - 在 python/tkinter 上将值从子窗口传递到父窗口

python - Pandas :将日期时间时间线从一个数据帧强加到另一个数据帧

python - Pygame 绘制抗锯齿形状,然后传输到主窗口