如何避免python类中的图像垃圾收集?

时间:2017-10-04 01:50:46

标签: python image class garbage-collection python-imaging-library

所以我在两周前就开始学习Python了,当涉及图像的垃圾收集时,我遇到了一个小问题。

具体来说,我正在尝试将图像加载到从XML文件中读取的工具栏上。我使用以下相关代码:

- run.py -

    sections['toolbar'] = Toolbar(sections)

- toolbar.py -

class Toolbar:
    def __init__(self, sections):
        # Make relevant variables easily accessible
        root = sections['root']

        # Create style
        ttk.Style().configure("Toolbar.TFrame", relief="raised")

        # Read toolbar data from XML file     
        toolbar_data = XMLParse("c:/PyApp/Builder/ui/toolbar.xml")
        toolbar_data = toolbar_data.read()

        # Create toolbar frame
        toolbar = ttk.Frame(root, style="Toolbar.TFrame")     

        # Loop through tools
        num = 0
        tool_img = []
        tool_button = []

        toolbar_datax = sorted(toolbar_data)                
        for tool in toolbar_datax:
            # Get tool id
            tool_id = toolbar_data[tool]['id']

            # Fetching tool image
            tool_img.append(PIL.ImageTk.PhotoImage(PIL.Image.open(toolbar_data[tool]['image'])))
            print(tool_img)

            # Creating tool button         
            tool_button.append(Button(toolbar, image=tool_img[num], relief=FLAT, command=lambda tool_id_ = tool_id : self.pressed(tool_id_)))

            # Add tool button to toolbar
            tool_button[num].pack(side=LEFT, padx=2, pady=2)
            num += 1

        # Ensure that images do not get garbage collected
        self.tool_img = tool_img

        # Add toolbar to root                
        toolbar.pack(side=TOP, fill=X)  

        # Make relevant variables accessible throughout class
        self.sections = sections

- 结果 -

[<PIL.ImageTk.PhotoImage object at 0x000001ED9A517198>]
---------------------------------------------------------------------------
TclError                                  Traceback (most recent call last)
(path)\run.py in <module>()
     36 # --- SHOW TOOLBAR ---
     37 
---> 38 sections['toolbar'] = Toolbar(sections)
     39 
     40 # --- FINISH TOOLBAR ---
(path)\toolbar.py in __init__(self, sections)
     40 
     41             # Creating tool button
---> 42             tool_button.append(Button(toolbar, image=tool_img[num], relief=FLAT, command=lambda tool_id_ = tool_id : self.pressed(tool_id_)))
     43 
     44             # Add tool button to toolbar
(path) in __init__(self, master, cnf, **kw)
   2207             overrelief, state, width
   2208         """
-> 2209         Widget.__init__(self, master, 'button', cnf, kw)
   2210 
   2211     def flash(self):
(path) in __init__(self, master, widgetName, cnf, kw, extra)
   2137             del cnf[k]
   2138         self.tk.call(
-> 2139             (widgetName, self._w) + extra + self._options(cnf))
   2140         for k, v in classes:
   2141             k.configure(self, v)
TclError: image "pyimage1" doesn't exist

如您所见,我打印tool_img列表以检查结果。此时图像仍然存在。

另外,我试图通过添加self.tool_img = tool_img来避免垃圾收集,但这不起作用。

此外,我尝试了另一种解决方案,我在其中创建了一个新类(Images),我在run.py中创建了一个对象。之后,我调整了工具栏类,首先将图像添加到对象中,然后调用它们,但结果相同。

我希望我提供了所有必要的信息,并希望能够朝着正确的方向努力。

提前致谢!

1 个答案:

答案 0 :(得分:0)

我设法创建了一个全新的结构,并使用包含对象引用的shared.py。然后我将图像添加到对象引用中,它现在正在工作。