简体   繁体   中英

Using 2d array to create clickable TKinter canvas

I want to create a TKinter canvas that consists of 5x5 cells in which you can click on any of the cells and change the color. For simplicity sake we are only dealing with black and white. I want to create this using a 2d 5x5 array that starts out all 0's indicating all white. When you click on a cell on the canvas it should change the corresponding spot on the 2d array to a 1 and change the color to black. here is what I have so far. I just don't know how to make the connection between the 2d array and the canvas. Also how do I fill the canvas with the clickable cells?

from tkinter import *

class CellArray():
    def __init__(self, root):
        self.board = [[0, 0, 0, 0, 0,]
                 [0, 0, 0, 0, 0,],
                 [0, 0, 0, 0, 0,],
                 [0, 0, 0, 0, 0,],
                 [0, 0, 0, 0, 0,],
                 [0, 0, 0, 0, 0,],]

class CellCanvas(Frame):
    def __init__(self, root):
        Frame.__init__(self, root)
        self.initBoard()

    def initBoard(self):
        self.display = Canvas(root, width=500, height=500, borderwidth=5, background='white')
        self.display.grid()

root = Tk()
board = CellCanvas(root)
root.mainloop()

You could place colored rectangles on the canvas on click and remove them when clicked again:

import Tkinter as tk

# Set number of rows and columns
ROWS = 5
COLS = 5

# Create a grid of None to store the references to the tiles
tiles = [[None for _ in range(COLS)] for _ in range(ROWS)]

def callback(event):
    # Get rectangle diameters
    col_width = c.winfo_width()/COLS
    row_height = c.winfo_height()/ROWS
    # Calculate column and row number
    col = event.x//col_width
    row = event.y//row_height
    # If the tile is not filled, create a rectangle
    if not tiles[row][col]:
        tiles[row][col] = c.create_rectangle(col*col_width, row*row_height, (col+1)*col_width, (row+1)*row_height, fill="black")
    # If the tile is filled, delete the rectangle and clear the reference
    else:
        c.delete(tiles[row][col])
        tiles[row][col] = None

# Create the window, a canvas and the mouse click event binding
root = tk.Tk()
c = tk.Canvas(root, width=500, height=500, borderwidth=5, background='white')
c.pack()
c.bind("<Button-1>", callback)

root.mainloop()

Try looping through the list, and with each entry bind the Button-1 event to the canvas object, so:

self.board = list([list(range(5)), list(range(5)), list(range(5)), list(range(5)), list(range(5))])
for x in range(0, 5, 1):
    for y in range(0, 5, 1):
         self.board[x][y] = Canvas(<your settings>)
         self.board[x][y].grid(row = x, column = y)
         self.board[x][y].bind('<Button-1>', <your click event>)

That should set you up nicely.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM