什么导致Tkinter画布的内存泄漏?

时间:2012-11-22 20:50:52

标签: python image canvas memory-leaks tkinter

使用以下代码,当小行星图像在屏幕上移动时,内存使用量会迅速增加,然后随着图像移动超出画布边缘而停止增加。谁能解释为什么会这样?我想在我的程序中无限期地在屏幕上移动图像,但它最终会占用我系统上的所有内存。

我是python,Tk和Tkinter的新手。关于canvas.move(...)或canvas.update()有什么明显的缺失吗?我应该使用不同的方法来完成这项任务吗?谢谢。

from Tkinter import Tk, Canvas, Frame, BOTH, NW
import Image 
import ImageTk
from random import random

root = Tk()
f = Frame(root)
f.pack(fill="both", expand=True)
canvas = Canvas(f, width=1000, height=1000)
canvas.pack(fill=BOTH, expand=1)

image = ImageTk.PhotoImage(Image.open("asteroid01.png"))
sprites = []
for i in range(10):
    sprites.append(canvas.create_image(50*random(), 50*random(), image=image))


vel = {'x': 1, 'y': 1}
while True:
    for s in sprites:
        canvas.move(s, vel['x'], vel['y'])
    canvas.update()

编辑:调用更新似乎是一种不好的做法,所以这里的代码按照建议进行了更改。但是,程序在图像移动时仍会消耗内存,并且在窗口关闭之前不会释放它。

from Tkinter import Tk, Canvas, Frame, BOTH, NW
import Image 
import ImageTk
from random import random

root = Tk()
f = Frame(root)
f.pack(fill="both", expand=True)
canvas = Canvas(f, width=1000, height=1000)
canvas.pack(fill=BOTH, expand=1)

image = ImageTk.PhotoImage(Image.open("asteroid01.png"))
sprites = []
for i in range(10):
    sprites.append(canvas.create_image(50*random(), 50*random(), image=image))

vel = {'x': 1, 'y': 1}

def move():
    for s in sprites:
        canvas.move(s, vel['x'], vel['y'])
    canvas.after(10, move)

move()
root.mainloop()

1 个答案:

答案 0 :(得分:0)

我的猜测是因为你在紧密循环中调用update。每次更新调用都会有效地创建一个新的事件循环。这可能就是在吞噬你的记忆。

相反,改变你的逻辑看起来像这样(未经测试,但应该非常接近正确):

def move():
    for s in sprites:
        canvas.move(s, vel['x'], vel['y'])
    canvas.after(10, move)
move()

你第一次调用move,然后它会在将来的某个时候再次调用它。数字的大小(以毫秒为单位)决定了对象移动的速度。

如果您希望能够停止动画,可以设置一个标志,然后在每次调用after之前检查该标志。