Pretty new to programming using Tkinter and I'm having a hard time with it. I'm trying to recreate this using python and what seems like to be the most appropriate library: Tkinter.
As seen in the video, I would like to be able to see my code "running" and would like to add a little sleep to the labyrinth creation. I've currently only created the grid and a function to color it. Although, I can't manage to get my window coloring rectangles one by one. Adding a sleep will block the program and without it, all the colors will appear all together.
All the solutions I've seen talks about labels with text modification but I cant' get it working for me. Am I missing something ?
Thanks for your help !
from tkinter import Tk, Canvas, Frame, BOTH
import random
from time import sleep
class Labyrinth(Frame):
def __init__(self):
super().__init__()
self.master.title("Laby")
self.pack(fill=BOTH, expand=1)
def creat_grid(self, square_side, laby_side):
grid = []
canvas = Canvas(self, width = laby_side * square_side, height = laby_side * square_side)
for y in range(laby_side):
subgrid = []
for x in range(laby_side):
if ((y % 2 == 0 or y == laby_side - 1 or x % 2 == 0) and not (x == 0 and y == 1) and not (x == laby_side - 1 and y == laby_side - 2)):
subgrid.append(1)
canvas.create_rectangle(square_side * x, square_side * y, square_side * x square_side, square_side * y square_side, fill="black")
else:
subgrid.append(0)
grid.append(subgrid)
canvas.pack(fill=BOTH, expand=1)
return canvas, grid
def color_grid(root, canvas, grid, square_side):
for y in range(len(grid)):
for x in range(len(grid)):
#sleep there blocks the program
if (grid[y][x] == 0 and not (x == 0 and y == 1) and not (x == len(grid) - 1 and y == len(grid) - 2)):
color = '#x' % random.randrange(16**3)
while (color in grid):
color = '#x' % random.randrange(16**3)
grid[y][x] = color
canvas.create_rectangle(square_side * x, square_side * y, square_side * x square_side, square_side * y square_side, fill=color)
#sleep there blocks the program
root.update()
#sleep there blocks the program
canvas.pack(fill=BOTH, expand=1)
def main():
root = Tk()
laby = Labyrinth()
square_side = 10
laby_side = 51
canvas, grid = laby.creat_grid(square_side, laby_side)
color_grid(root, canvas, grid, square_side)
root.mainloop()
if __name__ == '__main__':
main()
CodePudding user response:
You can use .after()
to simulate the running effect. Also it is better to create the to-be-filled rectangles once and then update their colors one by one using .after()
:
from tkinter import Tk, Canvas, Frame, BOTH
import random
class Labyrinth(Frame):
def __init__(self):
super().__init__()
self.master.title("Laby")
self.pack(fill=BOTH, expand=1)
def create_grid(self, square_side, laby_side):
grid = []
canvas = Canvas(self, width=laby_side*square_side, height=laby_side*square_side, bg='black', highlightthickness=0)
# create the to-be-filled rectangles
for y in range(1, laby_side, 2):
for x in range(1, laby_side, 2):
x1, y1 = x*square_side, y*square_side
grid.append(canvas.create_rectangle(x1, y1, x1 square_side, y1 square_side, fill='white'))
canvas.pack()
return canvas, grid
# create set of colors
colors = [f'#{x:03x}' for x in range(0x1000)]
# shuffle the colors in random order
random.shuffle(colors)
def color_grid(canvas, grid, i=0):
canvas.itemconfig(grid[i], fill=colors[i])
if i < len(grid)-1:
# adjust the delay to suit your running effect
canvas.after(5, color_grid, canvas, grid, i 1)
def main():
root = Tk()
laby = Labyrinth()
square_side = 10
laby_side = 51
canvas, grid = laby.create_grid(square_side, laby_side)
color_grid(canvas, grid)
root.mainloop()
if __name__ == '__main__':
main()