You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tkinter图片仅在对应类调用mainloop()时显示的问题求助

问题分析

你遇到的图片显示异常,核心原因和mainloop()的调用位置无关,而是Python垃圾回收机制导致的图片对象丢失:ImageTk.PhotoImage对象如果没有被持久化引用(比如仅作为局部变量存在),当所在方法执行完毕后,对象会被垃圾回收,从而无法在界面上显示。你之前在不同位置调用mainloop()时,对应类的局部img变量刚好还在作用域内没被回收,所以能临时显示,但这是偶然现象,不是正确解法。

解决方案

只需要给每个图片对象添加持久化引用(绑定为类的实例属性),然后仅调用一次mainloop()就能让所有图片正常显示。修改后的完整代码如下:

import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk

class BaseWindow(tk.Tk):
    def __init__(self):
        super(BaseWindow, self).__init__()
        self.geometry("800x700")
        self.title("test title")

        frame = ttk.Frame(self)
        frame.pack()
        ttk.Label(frame, text="test label").pack()
        # 将图片保存为实例属性,避免被垃圾回收
        self.img = ImageTk.PhotoImage(Image.open("res/male_avatar.png").resize((200, 200)))
        ttk.Label(frame, image=self.img).pack()

        frame_parent = ttk.Frame(self)
        frame_parent.pack()

        ParentWindow(frame_parent, self)
        # 仅在这里调用一次mainloop即可
        self.mainloop()


class ParentWindow(ttk.Frame):
    def __init__(self, parent, app):
        super(ParentWindow, self).__init__(parent)
        self.pack()
        ttk.Label(self, text="parent label test").pack()

        # 保存为实例属性
        self.img = ImageTk.PhotoImage(Image.open("res/male_avatar.png").resize((200, 200)))
        ttk.Label(self, image=self.img).pack()
        ttk.Label(self, text="test label").pack()

        frame_child = ttk.Frame(self)
        frame_child.pack()

        ChildWindow(frame_child, app)


class ChildWindow(ttk.Frame):
    def __init__(self, parent, app):
        super(ChildWindow, self).__init__(parent)
        self.pack()
        ttk.Label(self, text="child label test").pack()

        # 保存为实例属性
        self.img = ImageTk.PhotoImage(Image.open("res/male_avatar.png").resize((200, 200)))
        ttk.Label(self, image=self.img).pack()
        ttk.Label(self, text="test label").pack()


if __name__ == '__main__':
    BaseWindow()
关键说明
  • 把每个类中的局部变量img改为实例属性self.img,让图片对象绑定到类实例上,确保Python垃圾回收机制不会销毁它。
  • 仅需调用一次mainloop():可以在BaseWindow的__init__方法末尾调用self.mainloop(),或者在主入口中写BaseWindow().mainloop(),两种方式都能让所有图片正常显示。
  • 无需强制传递app对象给子类(除非有其他业务逻辑需要),图片显示异常的核心是引用丢失,和mainloop的调用位置无关。

内容的提问来源于stack exchange,提问作者Chrishdev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 04:15:18