简体   繁体   English

2d数组中的Tkinter按钮绑定到同一命令

[英]Tkinter Buttons in a 2d array get bound to the same command

I am making a simple program that creates a 3x3 matrix of tkinter.Button() and when a button is pressed it should display the "Clicked" text on it. 我正在制作一个简单的程序,该程序创建tkinter.Button()的3x3矩阵,当按下按钮时,它应该在上面显示“ Clicked”文本。 But the result seems like buttons that lie on the same column get bound to the same command - the one that targets the button of the last row of that column. 但是结果似乎是位于同一列上的按钮被绑定到同一命令-以该列最后一行的按钮为目标的命令。

from tkinter import *

root = Tk()

text = [[None]*3]*3
buttons = [[None]*3]*3

def action(i, j):
    text[i][j].set('Clicked')

for i in range(3):
    for j in range(3):
        text[i][j] = StringVar()
        text[i][j].set('(%d, %d)' % (i,j))
        buttons[i][j] = Button(root, command = lambda i=i, j=j : action(i, j))
        buttons[i][j].config(textvariable = text[i][j], width = 9, height = 5)
        buttons[i][j].grid(row = i, column = j)

root.mainloop()

图片在这里

The problem is not in your commands, but in the way you create your lists. 问题不在于您的命令,而在于创建列表的方式。

When you multiply a list, you actually multiply a reference to this single list (see this question ). 当您将一个列表相乘时,实际上是对该单个列表的引用也相乘(请参阅此问题 )。 You can see this when running the following code: 运行以下代码时,您可以看到此信息:

text = [[None]*3]*3
print([id(x) for x in text])

So when you change an item in one of the lists, the item is changed in all lists. 因此,当您更改其中一个列表中的项目时,该项目在所有列表中都会更改。 Therefore your list doesn't look like [[1,2,3],[4,5,6],[7,8,9]] , but like [[7,8,9],[7,8,9],[7,8,9]] . 因此,您的列表看起来不像[[1,2,3],[4,5,6],[7,8,9]] ,而是像[[7,8,9],[7,8,9],[7,8,9]] Then, when you think you set StringVar number 1, you actually set Stringvar number 7 so button number 7 is changed. 然后,当您认为设置StringVar数字1时,实际上是设置Stringvar数字7,因此更改了按钮数字7。

You can create three separate lists by using list comprehension instead of multiplication. 您可以使用列表理解而不是乘法来创建三个单独的列表。 As you can see with the following code, this produces three separate lists. 如下面的代码所示,这将生成三个单独的列表。

text = [[None]*3 for _ in range(3)]
print([id(x) for x in text])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM