我正在尝试编写一个Tkinter代码,如果按下名为“Rain”的按钮,那么看起来像雨的图像会开始移动。
我还不知道图像移动部分是如何工作的,但问题是当我点击“Rain”按钮时,它会写入 - > “Rain”就像它应该但Canvas上没有图像。
另一个有趣的事情是,当我采取
这是我的代码:
root = Tk()
#Create the canvas
canvas = Canvas(width=1000, height=1000)
canvas.pack()
#This is the part that does not work
#Nothing appears when this function is called
def Rain():
image3 = "Drops.png"
drops = PhotoImage(file = image3)
drops_background = canvas1.create_image(100, 100, image=drops)
while True:
canvas1.move(drops_background, 10, 10)
print("Rain")
#Adding a button and making it to use function "Rain"
frame = Frame(root)
frame.pack()
button1 = Button(frame, text = "Rain", command = Rain, fg = "red" ).pack(side = LEFT)
root.mainloop()
另一件有趣的事情是,如果我把这个部分放在功能之外就开始工作了。
image3 = "Drops.png"
drops = PhotoImage(file = image3)
drops_background = canvas1.create_image(100, 100, image=drops)
如果有人能告诉我这里有什么问题,或者至少指出我正确的方向,这将帮助我很多。
答案 0 :(得分:2)
PhotoImage
(或更确切地说是PIL
和Pillow
模块)中存在问题 - 必须将PhotoImage
分配给全局变量。
如果将PhotoImage
分配给局部变量,则Garbage Collector
将其从内存中删除。
我的完整工作示例after
import Tkinter as tk
import random
# --- globals ---
drops_background = None
drops = None
# --- functions ---
def rain():
global drops_background
global drops
filename = "Drops.png"
drops = tk.PhotoImage(file=filename) # there is some error in PhotoImage - it have to be assigned to global variable
drops_background = canvas.create_image(100, 100, image=drops)
# move after 250ms
root.after(250, move) # 250ms = 0.25s
def move():
global drops_background
# TODO: calculate new position
x = random.randint(-10, 10)
y = random.randint(-10, 10)
# move object
canvas.move(drops_background, x, y)
# repeat move after 250ms
root.after(250, move) # 250ms = 0.25s
# --- main ----
root = tk.Tk()
#Create the canvas
canvas = tk.Canvas(root, width=1000, height=1000)
canvas.pack()
#This is the part that does not work
#Nothing appears when this function is called
#Adding a button and making it to use function "Rain"
frame = tk.Frame(root)
frame.pack()
button1 = tk.Button(frame, text="Rain", command=rain, fg="red" )
button1.pack(side=tk.LEFT)
root.mainloop()
after
在给定时间后将功能和时间添加到其列表中并从此列表中运行mainloop
运行函数。
after
期望函数名称不包含()