如何修复Tkinter Notebook循环添加标签图标仅最后一个生效的问题?
问题修复方案
问题原因
这是Tkinter的PhotoImage对象的垃圾回收机制导致的:Python会自动回收没有被引用的对象,你在循环中每次创建的icon变量会被下一次迭代覆盖,之前的PhotoImage对象失去引用后就被销毁了,所以只有最后一个标签的图标能保留(因为它的icon变量还存在)。另外你所有标签的图标路径都是同一个,所以最后显示的是重复的同一张图标。
修复方法
只需要给每个PhotoImage对象保留一个持久化的引用即可,有两种简单的实现方式:
方式一:将图标绑定到对应的Frame组件
把图标对象赋值给对应Frame的属性,这样只要Frame存在,图标就不会被回收:
for i,v in enumerate(mainAppTabs): v.insert(1, Frame(mainAppNotebook, width=850, height=300)) v[1].grid_propagate(False) icon = PhotoImage(file=v[2]) # 把图标绑定到Frame上,保留引用 v[1].tab_icon = icon mainAppNotebook.add(v[1], text = v[0].title(), image = icon, compound = "left")
方式二:用列表存储所有图标引用
提前创建一个列表来保存每个PhotoImage对象,确保它们始终被引用:
# 初始化一个列表用来保存图标引用 icon_refs = [] for i,v in enumerate(mainAppTabs): v.insert(1, Frame(mainAppNotebook, width=850, height=300)) v[1].grid_propagate(False) icon = PhotoImage(file=v[2]) icon_refs.append(icon) mainAppNotebook.add(v[1], text = v[0].title(), image = icon, compound = "left")
额外提示
你当前的mainAppTabs列表中所有标签的图标路径都是getcwd()+"/icons/homeIcon.png",所以即使修复后所有标签显示的还是同一个图标。如果需要每个标签用不同图标,要修改路径,比如把log对应的图标改成getcwd()+"/icons/logIcon.png"之类的。
内容的提问来源于stack exchange,提问作者hfaulkner
相关产品推荐
相关产品推荐

