Tkinter设置窗口图标报错:无法使用pyimage5作为iconphoto
问题原因与解决方案
报错原因
你遇到的_tkinter.TclError: can't use "pyimage5" as iconphoto: not a photo image错误,核心原因是局部变量的垃圾回收:
- 在
ViewyPagey函数中,icon是局部变量,函数执行完成后,Python的垃圾回收机制会销毁这个变量对应的图片对象。 - 当Tkinter尝试用这个已被销毁的图片设置窗口图标时,就会报错提示它不是有效的图片。
- 另一个函数
ViewyPageyAdmin能运行只是巧合(比如其他控件的存在让图片对象暂时未被回收),实际上它也存在相同的潜在问题。
解决方法
方法1:给窗口绑定图片引用
修改ViewyPagey函数,把icon变量绑定到窗口对象上,让窗口持有图片的引用,避免被垃圾回收:
def ViewyPagey(): ViewPage=tkinter.Tk() ViewPage.title("View Database") ViewPage.resizable(False,False) ViewPage.configure(bg="#0073CF") frame1=tkinter.Frame(ViewPage, bg="#0073CF") frame1.grid(column=0, row=0) dir_path = os.path.dirname(os.path.realpath(__file__)) file_name = os.path.join(dir_path, "images\\nhslogo5.png") icon=ImageTk.PhotoImage(Image.open(file_name)) # 把icon绑定到窗口对象,添加这一行 ViewPage.icon = icon ViewPage.wm_iconphoto(False, icon)
方法2:规范使用Tkinter窗口(推荐)
Tkinter程序应该只有一个主窗口(用tkinter.Tk()创建),所有后续的子窗口应该使用tkinter.Toplevel(),这能避免很多Tcl层面的资源冲突问题。如果ViewyPagey是从主窗口打开的子窗口,修改如下:
def ViewyPagey(): # 用Toplevel创建子窗口,替换原来的tkinter.Tk() ViewPage=tkinter.Toplevel() ViewPage.title("View Database") ViewPage.resizable(False,False) ViewPage.configure(bg="#0073CF") frame1=tkinter.Frame(ViewPage, bg="#0073CF") frame1.grid(column=0, row=0) dir_path = os.path.dirname(os.path.realpath(__file__)) file_name = os.path.join(dir_path, "images\\nhslogo5.png") icon=ImageTk.PhotoImage(Image.open(file_name)) # 同样绑定引用 ViewPage.icon = icon ViewPage.wm_iconphoto(False, icon)
内容的提问来源于stack exchange,提问作者LewOF04
相关产品推荐
相关产品推荐

