Кнопки Tkinter в 2d массиве привязываются к одной и той же команде - PullRequest
0 голосов
/ 28 января 2019

Я делаю простую программу, которая создает матрицу 3x3 tkinter.Button(), и при нажатии кнопки на ней должен отображаться текст «Нажатие».Но результат выглядит так, как будто кнопки, лежащие в одном столбце, связаны с одной и той же командой - той, которая предназначена для кнопки последнего ряда этого столбца.

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

Image here

1 Ответ

0 голосов
/ 28 января 2019

Проблема не в ваших командах, а в том, как вы создаете свои списки.

Когда вы умножаете список, вы фактически умножаете ссылку на этот единственный список (см. этот вопрос ).Это можно увидеть, выполнив следующий код:

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])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...