0
使用下面的代码,随着小行星图像在屏幕上移动,内存使用量迅速增加,然后随着图像移出画布边缘而停止增加。谁能解释为什么会发生这种情况?我想保持一个图像在我的程序中无限期地在屏幕上移动,但它最终会占用我系统上的所有内存。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()
我仍然需要在move()内调用canvas.update(),虽然对吗?这样做我仍然有内存泄漏,即使在设置为1000之后。你能解释一下“事件循环”是什么意思吗? update()创建什么事件循环?我知道root.mainloop()将启动一个事件循环来寻找与窗口的交互。 canvas.update()不仅仅是重画画布吗? – user487100
@ user487100:没有。作为一般的经验法则,你应该_不要叫'update'。不,'canvas.update()'不会更新画布。它创建了一个新的事件循环,就像'mainloop'一样。事件循环只是一个看起来像“while True:wait_for_event(); process_event()”的内部函数。当你调用'mainloop()'的时候,它会这样做,并且每次你调用'update()'的时候都会这样做,所以你最终会在一个循环内的一个循环内产生一个循环... –
我没有意识到它不会重新调用update。我仍然看到内存泄漏。我会更新我在我的问题中使用的代码。你可以看一下吗? – user487100