使用以下代码,当小行星图像在屏幕上移动时,内存使用量会迅速增加,然后随着图像移动超出画布边缘而停止增加。谁能解释为什么会这样?我想在我的程序中无限期地在屏幕上移动图像,但它最终会占用我系统上的所有内存。
我是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()
答案 0 :(得分:0)
我的猜测是因为你在紧密循环中调用update。每次更新调用都会有效地创建一个新的事件循环。这可能就是在吞噬你的记忆。
相反,改变你的逻辑看起来像这样(未经测试,但应该非常接近正确):
def move():
for s in sprites:
canvas.move(s, vel['x'], vel['y'])
canvas.after(10, move)
move()
你第一次调用move,然后它会在将来的某个时候再次调用它。数字的大小(以毫秒为单位)决定了对象移动的速度。
如果您希望能够停止动画,可以设置一个标志,然后在每次调用after
之前检查该标志。