Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Tkinter刷新画布_Python_Canvas_Tkinter - Fatal编程技术网

Python Tkinter刷新画布

Python Tkinter刷新画布,python,canvas,tkinter,Python,Canvas,Tkinter,您好,我在python中有一个元组,其颜色与画布中由以下词典绘制的正方形相关: colour_mapping = {0: "red", 1: "green", 2: "blue" , 3:"purple"} 更具体地说,例如元组处的节点是: ((2, 3), (3, 3)) 这意味着应以这种方式绘制4个正方形: blue square purple square purple square purple square 然后它们的颜色应该根据元组中的下一个节点相应地改变 为此,

您好,我在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

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

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

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

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

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

for i in range(len(path)) :

但这确实是一个猜测,因为正如我所说,我不完全理解发生了什么。如果你能回答我的一些问题,我会尽力帮助你。抱歉,我没有更多帮助。

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

快速修复方法是调用
self.canvas.update\u idletasks
,但这只是一种黑客行为,不是一个合适的解决方案

制作动画的正确方法是使用事件循环进行迭代。您可以通过将要完成的工作放置在队列上来实现这一点——在本例中,是空闲事件队列。您可以使用
after
命令将内容放置在此队列上

您应该做的是编写一个函数,对动画进行一次迭代。本质上,将while循环中的所有内容移动到函数中。然后,只要有工作要做,就安排不断调用该函数。您可以在该函数中的之后调用
,也可以使用单独的函数控制动画

大致来说,解决方案如下所示:

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毫秒内绘制下一帧。当然,可以将该值设置为任意值,以控制动画的速度


这个网站上有这种技术的工作实例。例如,请参见

链接似乎是dead@rpax:不幸的是,有人决定我链接到的问题不应该只关闭,而应该删除。我不明白其中的道理。谢谢你让我知道。我已将链接替换为另一个链接。仅使用
self.canvas.update\u idletasks
是否有任何不利之处?因为它以最小的努力出色地解决了我的问题。