Python Tkinter刷新画布 [英] Python Tkinter refresh canvas

查看:553
本文介绍了Python Tkinter刷新画布的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Hello I have a tuple in python with colours that are related to squares that are drawn in the canvas by the following dictionary:

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

例如,更具体地说明元组处的节点:

To be more specific for example a node at the tuple is:

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

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

This means that 4 squares should be drawn this way:

blue square    purple square
purple square     purple square

,然后将它们的颜色更改为元组中的下一个节点

and then their colours should be changed accordingly to the next node in my tuple

为此,我要遍历元组然后为每个元素在画布上绘制一个新的矩形,然后调用 time.sleep()函数,以便给用户时间以查看其差异。以前的状态。
我的问题是只有最后一个节点正确呈现,而其他所有节点均未显示。您能帮我吗?

To do this I iterate the tuple and for each element I draw a new rectangle at the canvas and then I call the time.sleep() function in order to give time to the user to see the differences to the previous state. My problem is that only the last node is rendered correctly while all the others aren't shown. Can you help me?

到目前为止,这是我的代码:

Here is my code so far:

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

总而言之,我尝试制作上述动画。有什么我认为不正确的东西或在每次循环时刷新画布的东西吗?

All in all, I try to make an animation described above. Is there anything I don't think correctly or something to refresh the canvas at each loop?

推荐答案

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

The only way for the canvas to refresh is for the event loop to service "redraw" events. In your loop you're never giving the event loop a chance to update, so you don't see any changes.

快速的解决方法是调用 self.canvas.update_idletasks ,但这只是黑客,而不是适当的解决方案。

The quick fix is to call self.canvas.update_idletasks, but that's just a hack and not a proper solution.

制作动画的正确方法是使用事件循环进行迭代。通过将要完成的工作放在队列中(在本例中为空闲事件队列)来完成此操作。您可以使用 after 命令后将其放入此队列。

The proper way to do animation is to use the event loop to do the iterations. You do this by placing work to be done on a queue -- in this case, the idle event queue. You can place things on this queue with the after command.

您应该做的是编写一个函数动画的一次迭代。本质上,将所有内容放入while循环中并将其移至函数中。然后,安排有工作要做的连续调用该函数。您可以在该函数中的之后处调用,也可以使用一个单独的函数来控制动画。

What you should do is write a function that does one iteration of your animation. Essentially, take everything in your while loop and move it to a function. Then, arrange for that function to be continually be called as long as there is work to do. You can either place the call to after in that function, or have a separate function controlling the animation.

说来,解决方案看起来像这样:

Roughly speaking, the solution looks like this:

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)

$ b需要绘制一帧


$ b

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

This will draw one frame of your animation, check to see if there are any new frames to be drawn, and then arranges for the next frame to be drawn in 10ms. Of course, you can set that value to whatever you want in order to control the speed of the animation.

此网站上有此技术的有效示例。例如,请参见 https://stackoverflow.com/a/25431690/7432

There are working examples of this technique on this website. For example, see https://stackoverflow.com/a/25431690/7432

这篇关于Python Tkinter刷新画布的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆