SgtSafety SgtSafety - 5 months ago 57
Python Question

tkinter Multiple Buttons Colour Change

I'm using tkinter to create a 8x8 button matrix, which when the individual buttons are pressed add to a final list (eg finalList = ((0,0),(5,7),(6,6), ...), allowing me to quickly create 8x8 (x,y) co-ordinate images. I have created the window with the buttons but now have issues trying to reference these buttons in a function to add to a list or even change the colour of the button

I have read that once the button is created and you create another it moves to that button reference. I suspect I need to use a dict or 2D array to store all these reference of buttons but am struggling to figure out a solution.

from tkinter import *

class App:

def updateChange(self):
'''
-Have the button change colour when pressed
-add coordinate to final list
'''
x , y = self.xY
self.buttons[x][y].configure(bg="#000000")

def __init__(self, master):
frame = Frame(master)
frame.pack()

self.buttons = [] # Do I need to create a dict of button's so I can reference the particular button I wish to update?
for matrixColumn in range(8):
for matrixRow in range(8):
self.xY = (matrixColumn,matrixRow)
stringXY = str(self.xY)
self.button = Button(frame,text=stringXY, fg="#000000", bg="#ffffff", command = self.updateChange).grid(row=matrixRow,column=matrixColumn)
self.buttons[matrixColumn][matrixRow].append(self.button)


root = Tk()
app = App(root)
root.mainloop()


Example of the 8x8 Matrix

Answer

Below are 2 examples, the first is if you just want to change the colour and nothing else then you can do it without using a list. The second involves using a list and demonstrates what Delioth has pointed out

class App(object):
    def __init__(self, master):
        self._master = master

        for col in range(8):
            for row in range(8):
                btn = tk.Button(root, text = '(%d, %d)' % (col, row), bg = 'white')
                btn['command'] = lambda b = btn: b.config(bg = 'black')
                btn.grid(row = row, column = col)

class App(object):
    def __init__(self, master):
        self._master = master
        self._btn_matrix = []

        for col in range(8):
            row_matrix = []
            for row in range(8):
                btn = tk.Button(root, text = '(%d, %d)' % (col, row), bg = 'white',
                                command = lambda x = row, y = col: self.update(x, y))
                btn.grid(row = row, column = col)
                row_matrix.append(btn)
            self._btn_matrix.append(row_matrix)

    def update(self, row, col):
        self._btn_matrix[col][row].config( bg = 'black' )

if __name__ == '__main__':
    root = tk.Tk()
    app = App(root)
    root.mainloop()