Python Tkinter加载图片:类内变量替代全局变量后无法显示
ImageTk.PhotoImage改用实例变量后图片无法显示的问题解决
问题描述
在compaClass类中定义两个方法:使用全局变量newImg1时,drawImgs方法能正常在canvas1上绘制图片;但替换为类实例变量self.img1后,图片无法显示且无报错,现象和未声明全局变量时一致。
修改前代码:
def drawImgs(self): canvas1.delete("all") canvas1.create_image(0, 0, anchor=NW, image=newImg1) def loadImg(self): global newImg1 ... newImg1 = ImageTk.PhotoImage(resized_image1)
修改后代码:
def drawImgs(self): canvas1.delete("all") canvas1.create_image(0, 0, anchor=NW, image=self.img1) def loadImg(self): global newImg1 ... self.img1 = ImageTk.PhotoImage(resized_image1)
问题原因与解决方法
这是ImageTk.PhotoImage的垃圾回收机制导致的:
- 全局变量
newImg1会被Python解释器持续持有引用,不会被垃圾回收,所以图片资源能被Canvas正常调用。 - 改用
self.img1后,如果compaClass的实例对象被Python垃圾回收(比如实例是局部变量,函数执行完毕后就被销毁),self.img1也会跟着被回收,Canvas找不到图片资源就无法显示。 - 另外你修改后的
loadImg方法还保留了global newImg1声明,这是多余的,虽然不直接引发问题,但应该删除避免混淆。
解决步骤:
- 确保
compaClass的实例在程序运行期间有持续有效的引用,比如不要把实例定义成局部变量(比如不要在某个函数内创建实例后就退出函数),可以把实例设为全局变量或者让其他持续存在的对象持有它的引用。 - 删除
loadImg方法里的global newImg1声明。 - 可以额外给Canvas绑定一个图片引用,进一步防止垃圾回收:
def drawImgs(self): canvas1.delete("all") canvas1.create_image(0, 0, anchor=NW, image=self.img1) canvas1.image = self.img1 # 给Canvas添加引用,避免图片被回收
内容的提问来源于stack exchange,提问作者peta
相关产品推荐
相关产品推荐

