我有一长串要加载到Tkinter
画布中的图像。
我发现,如果我在Tkinter实例上调用PIL.PhotoImage
之前创建mainloop
实例,则此方法有效。我将以下内容绑定到与按键或类似事件绑定的回调函数中:
def onkeypress( event )
canvas.itemconfig( canvas_image, image_content )
image_content = PIL.PhotoImage( file="myfile.jpg" )
mytk.bind( "<Key>", onkeypress )
mytk.mainloop()
...但是这要求我在启动主循环之前将整个图像库加载到内存中。如果我尝试仅根据需要创建每个PIL.PhotoImage
:
def onkeypress( event )
image_content = PIL.PhotoImage( file="myfile.jpg" )
canvas.itemconfig( canvas_image, image_content )
mytk.bind( "<Key>", onkeypress )
mytk.mainloop()
然后代码执行时没有给我错误,但是我看不到画布内容更改。
我需要怎么做才能更改画布内容?
答案 0 :(得分:1)
第一个问题是我可以在mainloop()
之后看到它的功能。在关闭tkinter实例之前,您无法在mainloop之后运行任何操作。因此,您将需要将函数移至mainloop以及绑定上方。另一个重要的问题是函数中的局部变量。您的函数创建了一个本地图像,该图像将在函数完成后消失,因此您需要在函数中将image_content
定义为全局图像。
在使用画布时也适用相同的规则,因此,如果以我下面的示例为例,也可以将其应用于您的需求。
这是一个简单的示例,说明了如何将引用也保存为图像,并在需要时随时使用按钮应用它们。
import tkinter as tk
from PIL import ImageTk
root = tk.Tk()
def change_color(img_path):
global current_image
current_image = ImageTk.PhotoImage(file=img_path)
lbl.config(image=current_image)
current_image = ImageTk.PhotoImage(file="red.gif")
lbl = tk.Label(root, image=current_image)
lbl.grid(row=0, column=0, columnspan=3)
tk.Button(root, text="RED", command=lambda: change_color("red.gif")).grid(row=1, column=0)
tk.Button(root, text="BLUE", command=lambda: change_color("blue.gif")).grid(row=1, column=1)
tk.Button(root, text="GREEN", command=lambda: change_color("green.gif")).grid(row=1, column=2)
root.mainloop()
结果:
答案 1 :(得分:-1)
这是因为tk
不会保存该图像对象的引用,因此GC将在函数作用域之后收集它,因为image_content
是最后一个引用,并且它消失了。
您可以通过长期参考轻松解决此问题。