如果在函数中创建,为啥 Tkinter 图像不显示?
Posted
技术标签:
【中文标题】如果在函数中创建,为啥 Tkinter 图像不显示?【英文标题】:Why does Tkinter image not show up if created in a function?如果在函数中创建,为什么 Tkinter 图像不显示? 【发布时间】:2022-01-19 15:45:20 【问题描述】:此代码有效:
import tkinter
root = tkinter.Tk()
canvas = tkinter.Canvas(root)
canvas.grid(row = 0, column = 0)
photo = tkinter.PhotoImage(file = './test.gif')
canvas.create_image(0, 0, image=photo)
root.mainloop()
它显示了图像。
现在,这段代码可以编译,但它没有显示图像,我不知道为什么,因为它是相同的代码,在一个类中:
import tkinter
class Test:
def __init__(self, master):
canvas = tkinter.Canvas(master)
canvas.grid(row = 0, column = 0)
photo = tkinter.PhotoImage(file = './test.gif')
canvas.create_image(0, 0, image=photo)
root = tkinter.Tk()
test = Test(root)
root.mainloop()
【问题讨论】:
effbot.org 已关闭。它的要点是图像是通过引用传递的。如果引用是对局部变量的引用,则引用的内存将被重用,并且引用变得陈旧。存储图像的变量应该与它出现的 Tk gui 对象在同一范围内(必须具有相同的生命周期)。 @maszoka:effbot.org
可能已关闭,但您仍然可以阅读链接 Why do my Tkinter images not appear?,感谢 Internet 档案库 wayback machine。
【参考方案1】:
变量photo
是一个局部变量,在类实例化后会被垃圾回收。保存对照片的引用,例如:
self.photo = tkinter.PhotoImage(...)
如果你对“tkinter image doesn't display”进行谷歌搜索,第一个结果是这样的:
Why do my Tkinter images not appear?(常见问题解答目前没有过时)
【讨论】:
lmao,很好的答案! 哇。他们认为这是 tkinter 中的错误吗?他们应该。 我发现了一张很旧的票,已经关闭,没有修复:bugs.python.org/issue632323 链接在atm无效,除了使用“global”还有其他方法吗? @TamasHegedus:我同意这是一个错误,但显然在(目前)近二十年后没有人费心去修复它。已经数不清有多少次我看到一个关于它的问题仍然弹出。【参考方案2】:from tkinter import *
from PIL import ImageTk, Image
root = Tk()
def open_img():
global img
path = r"C:\.....\\"
img = ImageTk.PhotoImage(Image.open(path))
panel = Label(root, image=img)
panel.pack(side="bottom", fill="both")
but1 = Button(root, text="click to get the image", command=open_img)
but1.pack()
root.mainloop()
只需将全局添加到 img 定义中即可使用
【讨论】:
这个答案对于只使用函数的程序来说很好,但是如果像 OP 的情况一样,你使用一个类,那么global
不是不是的方法去吧。【参考方案3】:
只需将global photo
添加为函数内的第一行。
【讨论】:
然后你创建了第二个Test
实例,第一个实例丢失了它的图像。恭喜。
上课时绝对没有必要使用global
。 self.
负责所有这些。以上是关于如果在函数中创建,为啥 Tkinter 图像不显示?的主要内容,如果未能解决你的问题,请参考以下文章
在 scala 中创建的图像看起来不像预期的那样。不知道为啥