Home > Net >  Tkinter displaying only at the end of creation
Tkinter displaying only at the end of creation

Time:10-18

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()
  • Related