I am trying to simulate a grid like what would be used for a game board using tkinter rectangles being drawn onto a canvas, however I am having trouble making a loop that does so correctly.
Pretty much I have a variable that contains a certain amount of rows for a grid and a variable for the amount of columns, and I need to create a grid of rectangles based off of those configurations which can change anytime the application is run, which is making it a bit tricky for me.
Anyways, I currently have a function to draw a rectangle to the screen like so:
def _place_empty_tiles(self): self._canvas.update() width = self._canvas.winfo_width() height = self._canvas.winfo_height() self.x = width / self._game.columns self.y = height / self._game.rows for i in range(self._game.columns): click_point = point.from_pixel(self.x, self.y, width, height) self._state.handle_click(click_point) self.x += 60 def _redraw_game_pieces(self)->None: '''Delete and redraw all the of game pieces''' self._canvas.delete(tkinter.ALL) canvas_width = self._canvas.winfo_width() canvas_height = self._canvas.winfo_height() for tile in self._state.all_tiles(): center_x, center_y = tile.center().pixel(canvas_width, canvas_height) radius_x = tile.radius_frac() * canvas_width radius_y = tile.radius_frac() * canvas_height self._canvas.create_rectangle( center_x - radius_x, center_y - radius_y, center_x + radius_x, center_y + radius_y, fill = '#006000', outline = '#000000')
You may noticed I have some custom coordinate conversion methods going on to compensate for the screen re sizing. However, my problem is under the function
_place_empty_tiles(self) in the for loop. Let's say the amount of columns is 4, it will currently print out on the canvas the following:
- it is actually making a row, and
- that is only one row.
How can I make it so I can create a grid with a similar style given the amount of rows and columns are stored in
UPDATE: Tried basing it off The tkinter Knight's Tour Demo I rewrote the function like so:
def _place_empty_tiles(self): self._canvas.update() width = self._canvas.winfo_width() height = self._canvas.winfo_height() for r in range(self._game.rows -1,-1,-1): for c in range(self._game.columns): click_point = point.from_pixel(c*30+4, r*30+4, c*30+30, r*30+30) self._state.handle_click(click_point) self._redraw_game_pieces()
which is close, but still getting some unexpected results:
The Tk demos include a Knight's Tour demo that draws a chessboard. Someone converted it for tkinter and you can examine the
_draw_board function to see an example of how to create such a layout using canvas rectangles:
def draw_board(canvas): # draw checkerboard for r in range(7, -1, -1): for c in range(8): if c&1 ^ r&1: fill = 'tan3' dfill = 'tan4' else: fill = 'bisque' dfill= 'bisque3' coords = (c*30+4, r*30+4, c*30+30, r*30+30) canvas.create_rectangle(coords, fill=fill, disabledfill=dfill, width=2, state='disabled')