【问题标题】:Tkinter Buttons in a 2d array get bound to the same command二维数组中的 Tkinter 按钮绑定到相同的命令
【发布时间】:2019-01-28 10:59:44
【问题描述】:

我正在制作一个简单的程序,它创建一个tkinter.Button() 的 3x3 矩阵,当按下按钮时,它应该在其上显示“已单击”文本。 但结果似乎是位于同一列上的按钮被绑定到同一个命令 - 该命令以该列最后一行的按钮为目标。

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()

【问题讨论】:

    标签: python tkinter


    【解决方案1】:

    问题不在于您的命令,而在于您创建列表的方式。

    当您乘以一个列表时,实际上是乘以对该单个列表的引用(请参阅this question)。运行以下代码时可以看到:

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

    因此,当您更改其中一个列表中的项目时,该项目在所有列表中都会更改。因此,您的列表看起来不像[[1,2,3],[4,5,6],[7,8,9]],而是像[[7,8,9],[7,8,9],[7,8,9]]。然后,当您认为您设置了 StringVar 编号 1 时,您实际上设置了 Stringvar 编号 7,因此更改了 7 号按钮。

    您可以使用列表推导而不是乘法来创建三个单独的列表。正如您在以下代码中看到的那样,这会生成三个单独的列表。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-16
      • 2021-04-25
      • 1970-01-01
      • 2016-06-25
      • 2013-10-09
      相关资源
      最近更新 更多