Tkinter图片无法显示问题求助:函数内代码执行失效
问题解决:Tkinter函数内图片无法显示的问题
问题根源
你在BrowseCompter函数里创建的photo是局部变量,函数执行结束后,Python的垃圾回收机制会自动清理这个变量,导致Label组件失去图片对象的引用,所以图片无法正常显示。另外注意函数名拼写错误:BrowseCompter应为BrowseComputer(不影响运行,但建议修正以保证代码规范性)。
两种可行解决方案
方案1:将图片变量声明为全局变量
通过global关键字把photo提升为全局变量,避免函数执行完后被回收:
def BrowseComputer(): global filepath, photo filepath = filedialog.askopenfilename() photo = PhotoImage(file = filepath) print(filepath) # 先创建Label再调用grid,避免变量绑定到None(grid方法返回None) SelectedImage = Label(window, image=photo, bg="White") SelectedImage.grid(row=0,column=0)
方案2:将图片对象绑定到Label的属性上
不需要全局变量,把photo赋值给Label的自定义属性,让Label持有图片引用,阻止垃圾回收:
def BrowseComputer(): filepath = filedialog.askopenfilename() photo = PhotoImage(file = filepath) print(filepath) SelectedImage = Label(window, image=photo, bg="White") SelectedImage.image = photo # 绑定图片对象到Label属性 SelectedImage.grid(row=0,column=0)
额外提示:支持更多图片格式
PhotoImage默认仅支持PNG、GIF格式,如果需要加载JPG等其他格式,需借助PIL库的ImageTk模块。先安装pillow包,再修改代码:
from PIL import Image, ImageTk def BrowseComputer(): filepath = filedialog.askopenfilename() img = Image.open(filepath) photo = ImageTk.PhotoImage(img) SelectedImage = Label(window, image=photo, bg="White") SelectedImage.image = photo SelectedImage.grid(row=0,column=0)
完整修正后的代码
from tkinter import * from tkinter import filedialog # 窗口配置 window = Tk() window.title("TileSplit") window.configure(background="white") filepath = "" # 选择图片并显示 def BrowseComputer(): global filepath filepath = filedialog.askopenfilename() photo = PhotoImage(file = filepath) print(filepath) SelectedImage = Label(window, image=photo, bg="White") SelectedImage.image = photo # 绑定引用防止垃圾回收 SelectedImage.grid(row=0,column=0) # 文本标签配置 InstructionsLabel = Label(window, text="Please select the image you would like to split:" ,bg="white" ,font= "none 12 bold") EmptyLabel = Label(window, text="" ,bg="white" ,font= "none 12 bold") # 按钮配置 ImportImageButton = Button(window, text="Browse:", command=BrowseComputer) # 布局设置 InstructionsLabel.grid(row=0, column=60, sticky=E) ImportImageButton.grid(row=3,column=0) EmptyLabel.grid(row=1, column=0) # 启动主循环 window.mainloop()
内容的提问来源于stack exchange,提问作者Jonathan
相关产品推荐
相关产品推荐

