【问题标题】:How to avoid image garbage collection in python classes?如何避免 python 类中的图像垃圾收集?
【发布时间】:2018-03-15 07:34:54
【问题描述】:

所以我大约 2 周前开始学习 Python,但在图像的垃圾收集方面遇到了一个小问题。

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

-- 运行.py--

    sections['toolbar'] = Toolbar(sections)

-- 工具栏.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 来避免垃圾收集,但这不起作用。

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

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

提前致谢!

【问题讨论】:

  • 另外,打印 tool_img[num] 会给出 pyimage1 而不是图像对象。
  • 我现在尝试了几种不同的方法,包括使用全局变量导入共享模块。

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


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-29
    • 1970-01-01
    • 2017-11-16
    • 2018-04-08
    相关资源
    最近更新 更多