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
相关产品推荐
相关产品推荐

