pythontkinter

How to edit an element inside of a tkinter Grid?


I'm working on a project to design a chessboard.

I have successfully created the board. My goal is to edit the board.

My original idea is to use buttons with the Tkinter grid to make the moves work.

I decided to make the board using:

window = tk.Tk() # Creating the GUI and Display
window.geometry("800x500")
window.minsize(800, 500) #Locking the size of the Display
window.maxsize(800, 500)
    
#Adding the board
SeenBoard = tk.Frame(window, width=300, height=300,padx=5,pady=5) #Adds padding to the grid
SeenBoard.pack(side=tk.LEFT) #the left isnt needed yet, but will be later
    
for row in range(8): # 8 Rows along
    for column in range(8): #8 Columns down
        tk.Button(SeenBoard,text=f"{row},{column}",width=5,height=3).grid(row=row, column=column) #Creates each button
    
window.mainloop() #Idk what this really does? it just kinda works.

My problem is that with this way of making the board, I cannot edit the buttons, nor locate them.

Second solution to my knowledge:

My request:


Solution

  • To change the color of the checkerboard squares, one can make use of modulo 2. Here's a simple example showcasing that:

    from tkinter import tk
    
    COLOR_1 = "white"
    COLOR_2 = "green"
    
    for row in range(8): # 8 Rows along
        for column in range(8): #8 Columns down
            if (row + column) % 2:
                color = COLOR_1
            else:
                color = COLOR_2
            tk.Button(SeenBoard,text=f"{row},{column}",
                      width=5,
                      height=3,
                      bg=color).grid(row=row, column=column)
    

    The reason row is added to column is to achieve an alternating pattern.

    Consider a simple example of a 2x2 chessboard.

    row col row + col ( row + col ) % 2
    0 0 0 0
    0 1 1 1
    1 0 1 1
    1 1 2 0

    Which gives a pattern:

    +---+---+
    | 0 | 1 |
    +---+---+
    | 1 | 0 |
    +---+---+
    

    To access button objects in the future, simply store them in a nested list, using your row and column numbers as indexes:

    # create a list to hold the buttons
    array = list()
        
    for row in range(8):
        # Create an array to store a row of buttons
        array.append(list())
        for column in range(8):
            # Append each column to the corresponding row
            array[row].append(tk.Button(SeenBoard,text=f"{row},{column}",
                      width=5,
                      height=3,
                      ))
            # Add it to the grid
            array[row][column].grid(row=row, column=column)
    
    # Modify by using rows & columns as indexes
    array[3][2]["text"] = "It works!"
    

    This will also prevent your buttons from being garbage collected, since you're holding a reference to them.

    Output: Image of Chessboard prototype with entry 3,2 modified

    Notice how the button at (3,2) is modified to say It works!.

    As for the last question, the mainloop runs an event loop, which does two things:

    1. It prevents the program from exiting after the last line of code.
    2. It checks for events (such as a button press).

    (In reality, things might work differently, but this is what it generally does)