#python #tkinter
Вопрос:
Довольно новичок в программировании с использованием Tkinter, и мне это дается с трудом. Я пытаюсь воссоздать это с помощью python и, по-видимому, наиболее подходящей библиотеки: Tkinter.
Как видно из видео, я хотел бы видеть, как мой код «работает», и хотел бы добавить немного сна к созданию лабиринта. В настоящее время я создал только сетку и функцию для ее раскрашивания. Хотя мне не удается раскрасить прямоугольники моего окна один за другим. Добавление режима сна заблокирует программу, и без этого все цвета будут отображаться все вместе.
Все решения, которые я видел, говорят о ярлыках с изменением текста, но я не могу заставить их работать на меня. Я что-то упускаю ?
Спасибо за вашу помощь !
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()
Комментарии:
1. Дисплей не будет обновляться до тех пор, пока код не будет простаивать, чего не произойдет в циклах while (или в любом другом цикле). Реструктурируйте свою программу так, чтобы у вас была, например
next_step()
, функция, которая будет вызываться периодически или после каждого состояния простоя.
Ответ №1:
Вы можете использовать .after()
для имитации эффекта бега. Также лучше один раз создать прямоугольники для заполнения, а затем обновить их цвета один за другим с помощью .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()