如何在不重绘每个元素的情况下更新画布?

时间:2014-09-19 04:41:23

标签: tkinter

让我们说我有一个画布,它有一些从tkinter形状中抽出的背景,并且在顶部我移动了一个圆圈。

是否可以仅重绘圆圈,而不是每次都重绘背景?

示例代码:

import  Tkinter

class gui(Tkinter.Tk):  

    def draw_background(self):
        self.canvas.create_oval(0,0, 500, 500, fill = 'black')

    def draw_circle(self,x, y):
        self.canvas.create_oval(x,y, x+10,y+10, fill = 'green')



    def __init__(self, parent):
        Tkinter.Tk.__init__(self, parent)
        self.guiHeight = 800
        self.guiWidth = 800
        self.initialise()

    def animation(self):

        self.x = self.x +1%100
        self.y = self.y +1%100

        self.canvas.delete("all")
        self.draw_background()      
        self.draw_circle(self.x, self.y)

        self.after(100,self.animation)

    def initialise(self):
        self.title('traffic')

        self.canvas = Tkinter.Canvas(self, height = self.guiHeight, width = self.guiWidth)
        self.draw_background()      
        self.canvas.pack()

        self.x = 0
        self.y = 0
        self.after(100, self.animation)
        self.mainloop()


if __name__ == "__main__":
    app = gui(None) 

这段代码将完全符合我的要求。绿点向右下角移动,并在背景圆圈顶部自动显示。

然而,告诉它每次都重绘背景图像似乎很浪费(想象一下,如果在绘制背景时涉及很多计算)是否可以在其上面的透明层显示,然后重新绘制图层?

1 个答案:

答案 0 :(得分:3)

您可以使用move方法移动画布上的任何项目。您还可以delete任意一个项目并重新绘制它。这些都不需要重绘任何其他对象。

创建项目时,会返回一个ID,您可以将其提供给移动或删除方法。

self.circle_id = self.canvas.create_oval(x,y, x+10,y+10, fill = 'green')
...
# move the circle 10 pixels in the x and y directions
self.canvas.move(self.circle_id, 10,10)

您还可以为一个或多个元素提供标记(实际上是标记列表),然后在单个命令中移动或删除具有该标记的所有元素:

self.canvas.create_oval(x, y, x+10, y+10, fill='green', tags=("circle",))
...
self.canvas.move("circle", 10, 10)

您还可以计算圆圈的所有新坐标,然后使用coords方法进行更新:

# make the upper-left corner 0,0 and the lower right 100,100
self.canvas.coords("circle", 0,0,100,100)