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