为什么在函数中创建的 Tkinter 图像不会显示?
- 2024-11-15 08:36:00
- admin 原创
- 14
问题描述:
此代码有效:
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()
解决方案 1:
该变量photo
是一个局部变量,在类实例化后会被垃圾收集。解决方案涉及保存对照片的引用,例如:
self.photo = tkinter.PhotoImage(...)
如果你用 Google 搜索“tkinter 图像不显示”,第一个结果是这样的:
为什么我的 Tkinter 图像没有出现?
解决方案 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()
只需将 global 添加到 img 定义即可
解决方案 3:
问题是 Python 通过一个称为垃圾收集的过程自动删除对变量的引用。 解决方案是保存引用或创建新引用。
方法如下:
用来
self
增加引用计数并保存引用。
import tkinter
class Test:
def __init__(self, master):
canvas = tkinter.Canvas(master)
canvas.grid(row = 0, column = 0)
self.photo = tkinter.PhotoImage(file = './test.gif') # Changes here
canvas.create_image(0, 0, image=self.photo) # Changes here
root = tkinter.Tk()
test = Test(root)
root.mainloop()
将其保存到列表中以增加引用计数并保存引用。
import tkinter
l=[]
class Test:
def __init__(self, master):
canvas = tkinter.Canvas(master)
canvas.grid(row = 0, column = 0)
photo = tkinter.PhotoImage(file = './test.gif')
l.append(photo)
canvas.create_image(0, 0, image=photo)
root = tkinter.Tk()
test = Test(root)
root.mainloop()
使用方法 2 时,您可以像我一样创建全局列表,也可以在类中使用列表。 两种方法都可以。
一些有用的链接:
关于垃圾回收 1
关于垃圾收集 2(更有用)
解决方案 4:
根据经验,每当您在缩进的代码块中创建图像时,都需要安全地引用该图像。这是因为python的自动垃圾收集,当它破坏/离开该框架/页面/缩进的代码块时,它会收集引用计数为0的所有内容。
处理此问题的规范方法是将图像列表放在全局命名空间中的某个位置,然后将图像引用添加到该列表中。这很方便,但效率不高,应该用于小型应用程序。
import tkinter as tk
global_image_list = []
global_image_list.append(tk.PhotoImage(file = 'test.png'))
一种更有效的方法是将一个属性绑定到您的小部件或类self.image
,以便为您保存该引用,正如 Bryan 在他的回答中提出的那样。无论您这样做还是之前widget.image
已分配,都没有区别widget = tk.Widget(..
。但是,如果您想在小部件被销毁并被垃圾回收时继续使用该图像,这也可能不是正确的方法。
import tkinter as tk
root = tk.Tk()
label = tk.Label(root, text='test')
label.image = tk.PhotoImage(file = 'test.png')
label.configure(image=label.image)
解决方案 5:
只需将其添加global photo
为函数内的第一行。
相关推荐
热门文章
项目管理软件有哪些?
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件
热门标签
云禅道AD