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 に答える