0

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

我是 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()
4

1 回答 1

0

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

相反,将您的逻辑更改为如下所示(未经测试,但应该非常接近正确):

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

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

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

于 2012-11-22T21:34:03.070 回答