Python Tkinter刷新画布

2024-07-08 16:53:43 发布

您现在位置:Python中文网/ 问答频道 /正文

您好,我有一个python中的元组,其颜色与画布中由以下字典绘制的正方形相关:

colour_mapping = {0: "red", 1: "green", 2: "blue" , 3:"purple"}

更具体地说,例如元组中的节点是:

((2, 3), (3, 3))

这意味着4个正方形应该这样画:

blue square    purple square
purple square     purple square

然后它们的颜色应该相应地改变到元组中的下一个节点

为此,我迭代元组,并为每个元素在画布上绘制一个新的矩形,然后调用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

总之,我试着制作一个上面描述的动画。有没有什么我认为不正确的地方,或者在每个循环中刷新画布?


Tags: selfsize节点画布fillframestartpack
2条回答

画布刷新的唯一方法是事件循环为“重画”事件提供服务。在您的循环中,您永远不会给事件循环更新的机会,因此您看不到任何更改。

快速的解决方法是调用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)

这将绘制动画的一帧,检查是否有新的帧要绘制,然后安排下一帧在10毫秒内绘制。当然,可以将该值设置为所需的任何值,以控制动画的速度。

在这个网站上有这种技术的工作实例。例如,请参见https://stackoverflow.com/a/25431690/7432

首先,我有点困惑为什么((2,3)(3,3))会得到绿色和蓝色的正方形。你的颜色编码似乎表明它们是蓝色和紫色的,不是吗?

第二,我不能完全确定我是否理解“然后它们的颜色应该相应地改变到元组中的下一个节点”。这是否意味着在某一点上,你要通过((2,3)(3,3))并期望得到4个正方形,然后下一次通过((2,3)(3,3)(1,2))并期望6个正方形被绘制成蓝色?

第三,你的程序的输出是什么?似乎你有足够的打印语句,你应该能够找出问题所在。

在没有完全理解程序的情况下进行猜测,我猜问题在于一个for循环没有迭代正确的值,这导致没有绘制所有的正方形。我的猜测是第一个:

for i in range(len(path)) :

但这确实是一个猜测,因为正如我所说,我不完全理解正在发生的事情。如果你能回答我的一些问题,我会尽力帮忙的。对不起,我没有更多的帮助。

相关问题 更多 >

    热门问题