0

I'm trying to change the color of a button. Here is the code.

for i in range(6):
    for j in range (6):
        if i == 0 and j == 0:
            grids6 = tk.Button(mFrame, bg='blue', highlightcolor="black", highlightthickness=1, state = "disabled", width = 11, height = 5)
             grids6.grid(row = i, column = j)
        elif i == 5 and j == 5:
            grids6 = tk.Button(mFrame, bg='red', highlightcolor="black", highlightthickness=1, state = "disabled", width = 11, height = 5)
            grids6.grid(row = i, column = j)
        else:
            grids6 = tk.Button(mFrame, bg='black', highlightcolor="black", highlightthickness=1, state = "disabled", width = 11, height = 5)
            grids6.grid(row = i, column = j)
grids6[(3,4)].configure(background= 'red') # here is where I tried to change the color but with no success
Gary
  • 909
  • 8
  • 20
Hana
  • 5
  • 4
  • Does `grids6[(3,4)].config(bg= 'red')` work? – shahkalpesh Nov 27 '19 at 13:58
  • Exception in Tkinter callback TypeError: can only concatenate str (not "tuple") to str , i get these two errors – Hana Nov 27 '19 at 14:01
  • Look at [this](https://stackoverflow.com/questions/44588154/python-tkinter-how-to-config-a-button-that-was-generated-in-a-loop) to code your scenario better. – shahkalpesh Nov 27 '19 at 14:09
  • 2
    @Hana ***`grids6[(3,4)]`***: How do you expect that `grids6` is of type `dict` with key `(3,4)`. As it stands `grids6` is a object of type `tk.Button`. So this: `grids6.configure(background= 'red')` should work. Read about [Tkinter.Grid.grid_slaves-method](http://effbot.org/tkinterbook/grid.htm#Tkinter.Grid.grid_slaves-method) – stovfl Nov 27 '19 at 14:14
  • 1
    @stovfl it did work and only the last button got colored, but the question is how to specify which button to color – Hana Nov 27 '19 at 14:25
  • @stovfl [] – Hana Nov 27 '19 at 14:51
  • @Hana: My, bad. Returns always a `list` of `Button`. Should read `mFrame.grid_slaves(row=0, column=0)[0].configure(...` – stovfl Nov 27 '19 at 14:55
  • 1
    @stovfl oh yeees it did work, thanks a lot. One last question does [0] have a purpose – Hana Nov 27 '19 at 15:01
  • @Hana: ***"does [0] have a purpose"***: The return value is a `list` of `Button` objects. To access a item in a `list` you use it's index. The index of the first item in a `list` is `0`. Read [Common Sequence Operations](https://docs.python.org/3/library/stdtypes.html#index-22) and [how to use lists in Python](https://www.pythonforbeginners.com/lists/python-lists-cheat-sheet) – stovfl Nov 27 '19 at 15:12

1 Answers1

1

Question: How to access one Button in a grid of Button.

Using .grid(row=i, column=j) you layout widgets in a Row/Column manner.
To access, one of the widget later on, you can use grid_slaves(row=None, column=None).


This implements a OOP solution, to get your initial approach to work:

mFrame[(3,4)].config(bg= 'red')
class Board(tk.Frame):
    def __init__(self, parent, **kwargs):
        super().__init__(parent, **kwargs)

    def __getitem__(self, coord):
        if isinstance(coord, tuple):
            return self.grid_slaves(row=coord[0], column=coord[1])[0]


class Square(tk.Button):
    def __init__(self, parent, **kwargs):
        # Defaults
        kwargs['highlightcolor'] = "black"
        kwargs['highlightthickness'] = 1
        kwargs['state'] = "disabled"
        kwargs['width'] = 11
        kwargs['height'] = 5
        super().__init__(parent, **kwargs)

Usage

class App(tk.Tk):
    def __init__(self):
        super().__init__()
        self.geometry("800x600")

        board = Board(self)
        board.grid()

        for row in range(6):
            for column in range(6):
                if row == 0 and column == 0:
                    square = Square(board, bg='blue', )
                elif row == 5 and column == 5:
                    square = Square(board, bg='red', )
                else:
                    square = Square(board, bg='black', )

                square.grid(row=row, column=column)

        # Access the Square in Row index 3 and Column index 4,
        # using subscript the object `board` by `(3, 4)`.
        board[(3, 4)].configure(bg='red')

        # Extend, `class Board` to acces the first Square with (1, 1)
        # Allow only >= (1, 1) ans subtract 1
        # Or Layout Row/Column >= 1, 1
        # board[(1, 1)].configure(bg='yellow')


if __name__ == '__main__':
    App().mainloop()

Tested with Python: 3.5 - 'TclVersion': 8.6 'TkVersion': 8.6

Note: This will not work on MACOS, there you can't change the Background color of tk.Button. Replace tk.Button with tk.Canvas.

stovfl
  • 14,998
  • 7
  • 24
  • 51