JmR*_*Rag 7 python canvas tkinter
您好我在python中有一个元组,其颜色与通过以下字典在画布中绘制的正方形相关:
colour_mapping = {0: "red", 1: "green", 2: "blue" , 3:"purple"}
Run Code Online (Sandbox Code Playgroud)
更具体地说,例如元组中的节点是:
((2, 3), (3, 3))
Run Code Online (Sandbox Code Playgroud)
这意味着应该以这种方式绘制4个方格:
blue square purple square
purple square purple square
Run Code Online (Sandbox Code Playgroud)
然后他们的颜色应该相应地更改为我的元组中的下一个节点
为此,我迭代元组,对于每个元素,我在画布上绘制一个新的矩形,然后我调用该time.sleep()函数,以便给用户时间以查看与先前状态的差异.我的问题是只有最后一个节点正确呈现而其他所有节点都没有显示.你能帮助我吗?
到目前为止,这是我的代码:
self.parent.title("AlienTiles")
self.style = Style()
self.style.theme_use("default")
self.frame = Frame(self, relief=RAISED, borderwidth=1)
self.frame.pack(fill=BOTH, expand=1)
self.canvas = Canvas(self.frame)
self.canvas.pack(fill=BOTH, expand=1)
self.pack(fill=BOTH, expand=1)
for i in range(len(path)) : #the tuple is path
state = path[i].state
print state
time.sleep(1)
y_offset=10
for x in state:
start_x=40
start_y=10
i=1
x_offset=0
for y in x:
x0=(start_x*i)+x_offset
y0=(start_y*i)+y_offset
x1=x0+size
y1=y0+size
colour=colour_mapping[y]
print colour
self.canvas.create_rectangle(x0, y0, x1, y1, fill=colour)
x_offset=x_offset+size+10
y_offset=y_offset+size+10
Run Code Online (Sandbox Code Playgroud)
总而言之,我尝试制作上述动画.有什么我不正确的想法或在每个循环刷新画布的东西?
Bry*_*ley 13
画布刷新的唯一方法是为事件循环提供服务"重绘"事件.在你的循环中,你永远不会给事件循环提供更新的机会,所以你没有看到任何变化.
快速解决方法是打电话self.canvas.update_idletasks,但这只是一个黑客而不是一个合适的解决方案.
做动画的正确方法是使用事件循环来进行迭代.您可以通过在队列上放置要完成的工作来完成此操作 - 在本例中为空闲事件队列.您可以使用该after命令将事物放在此队列中.
你应该做的是编写一个函数,对你的动画进行一次迭代.基本上,将while循环中的所有内容都移到函数中.然后,只要有工作要做,就安排不断调用该功能.您可以将调用after放在该函数中,也可以使用单独的函数来控制动画.
粗略地说,解决方案看起来像这样:
def do_one_frame(self, ...):
# do whatever you need to draw one frame
if (there_is_more_work_to_be_done):
self.after(10, do_one_frame)
Run Code Online (Sandbox Code Playgroud)
这将绘制动画的一帧,检查是否有任何新帧要绘制,然后安排在10ms内绘制下一帧.当然,您可以将该值设置为您想要的任何值,以便控制动画的速度.
本网站上有这种技术的工作示例.例如,请参阅/sf/answers/1780218331/