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

Tkinter仅处理图片的面向对象界面初始化路径及帧销毁冲突问题

解决方案

一、事件冲突问题修复

原因

你当前将点击事件绑定到了Toplevel顶层窗口对象(self.master),该绑定关系不会随着子帧ImG的销毁自动解除,每次新建帧都会新增一次绑定,多次切换后就会出现事件重复触发的冲突。

解决方法

  • 优先将事件绑定到ImG帧实例自身,帧销毁时绑定事件会自动清理:
    把ImG类里的self.master.bind("<Button-1>", self.img_2)改为self.bind("<Button-1>", self.img_2),同时给img_2方法补充event参数(tkinter绑定事件的回调方法默认会传入事件对象)。
  • 如果业务必须绑定到顶层窗口,需在销毁旧帧前手动解绑,可重写帧的destroy方法实现:
class ImG(Frame):
    def __init__(self, master, **kwargs):
        super().__init__(master, **kwargs)
        self.img1 = PhotoImage(file= '60.png')
        self.lbl1 = Label(self, image=self.img1)
        self.lbl1.pack()
        # 存储绑定id
        self.bind_id = self.master.bind("<Button-1>", self.img_2)

    def img_2(self, event):
        print('new image N°24')

    # 重写destroy方法,销毁前先解绑
    def destroy(self):
        self.master.unbind("<Button-1>", self.bind_id)
        super().destroy()

二、启动慢性能优化

优化方案

性能瓶颈出在每次新建ImG实例都会重复从磁盘读取图片文件,你可以按以下层级优化:

  • 全局预加载:程序启动阶段就把Img_1到Img_60所有用到的图片一次性加载为PhotoImage实例,存储在全局列表/字典中,创建帧的时候直接引用预加载的实例即可,无需重复读盘。
  • 按需缓存:如果图片总大小过大占用内存过高,可以做LRU缓存,只保留最近使用的10-20张图片,避免频繁读盘。
  • 修正语法错误:原有代码存在类名拼写错误、方法定义缺空格、缺括号、回调方法缺参数等问题,修正后可避免不必要的运行开销。

修正后完整可运行代码

from tkinter import *

# 提前预加载图片示例,可扩展加载所有60张图
PRELOAD_IMGS = {
    "60": PhotoImage(file='60.png')
}

class Ctrl(Frame):
    def __init__(self, master, **kwargs):
        super().__init__(master, **kwargs)
        self._frame_1 = None
        self._open_1 = False
        self.button1 = Button(self, text='pack 1',
                      command= lambda:self.windows(ImG))
        self.button1.pack()

    def windows(self, var_1):
        if not self._open_1:
            self.top1 = Toplevel(self.master)
            self.top1.geometry('200x200')
                                
        container = var_1(self.top1)

        if self._frame_1 is not None:  
            self._frame_1.destroy()
        self._frame_1 = container
        self._frame_1.pack()
        self._open_1 = True

class ImG(Frame):
    def __init__(self, master, **kwargs):
        super().__init__(master, **kwargs)
        # 直接引用预加载的图片,不用重复读盘
        self.img1 = PRELOAD_IMGS["60"]
        self.lbl1 = Label(self, image=self.img1)
        self.lbl1.pack()
        # 绑定到自身,自动随销毁解绑
        self.bind("<Button-1>", self.img_2)

    def img_2(self, event):
        print('new image N°24')

root = Tk()
app = Ctrl(root, bg='black')
app.pack()
root.mainloop()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 01:18:03