如何在Tkinter的多个窗口之间共享访问图片列表
Tkinter多窗口图片共享报错解决方法
错误原因
该报错是Tkinter的底层机制限制导致的:
- 每个
Tk()实例都会启动独立的Tcl解释器上下文,不同上下文的资源(包括PhotoImage图片对象)完全隔离,无法跨实例调用 - 你代码里的image1、image2都是在第一个
Tk()实例(root)的上下文创建的,放到第二个Tk()实例(root2)的控件里自然识别不到
推荐解决方案
绝大多数多窗口场景都不要创建多个Tk()实例,第二个窗口改用Toplevel组件即可,所有子窗口共享主窗口的上下文,图片可以直接通用:
from tkinter import * from PIL import ImageTk, Image root = Tk() # 第二个窗口用Toplevel,不要新建Tk实例 root2 = Toplevel(root) image1 = ImageTk.PhotoImage(Image.open("Emoji/1.png")) image2 = ImageTk.PhotoImage(Image.open("Emoji/2.png")) button1 = Button(root, image = image2) button1.grid() button2 = Button(root2, image = image1) button2.grid() # 可选操作:绑定图片到控件属性,防止图片被垃圾回收后显示空白 button1.image = image2 button2.image = image1 mainloop()
特殊场景方案(不推荐)
如果你确实需要多个独立的Tk()实例,必须给每个图片对象指定对应的master参数,单独为每个窗口创建对应上下文的图片对象:
from tkinter import * from PIL import ImageTk, Image root = Tk() root2 = Tk() # 给每个图片指定所属的master image1_for_root2 = ImageTk.PhotoImage(Image.open("Emoji/1.png"), master=root2) image2_for_root = ImageTk.PhotoImage(Image.open("Emoji/2.png"), master=root) button1 = Button(root, image = image2_for_root) button1.grid() button1.image = image2_for_root button2 = Button(root2, image = image1_for_root2) button2.grid() button2.image = image1_for_root2 mainloop()
该方案会导致同一张图片要在多个上下文重复创建,浪费内存,且多Tk()实例容易出现事件响应、资源释放的异常,非必要不要使用。
内容的提问来源于stack exchange,提问作者Peaky Blinder
相关产品推荐
相关产品推荐

