Tkinter Canvas更新内存泄漏

时间:2013-10-06 18:38:53

标签: python canvas memory-leaks tkinter

我在下面的代码中看到内存泄漏。我在单独的模块中创建和处理我的数据,但这不会导致我看到的泄漏。我相信这是因为我每次改变比例时都会调用绘图类的新实例,尽管我不确定如何纠正这个问题。我已阅读this thread,但当我尝试在代码上实施self.canvas.destroy()方法时,我收到错误消息。我想知道下面的代码可以用什么方法来解决我的问题?

代码段:

from Tkinter import *

class Interface_On:

    def Interface_Elements(self, master):
        self.master=master
        self.master.title( "My Canvas")
        self.c=Canvas(self.master, width=1000, height=1000, bg='black')
        self.c.grid(row=0, column=0)
        menubar = Menu(master)
        filemenu = Menu(menubar, tearoff=0)
        filemenu.add_command(label="New", command=self.Edit_New)
        menubar.add_cascade(label="File", menu=filemenu)
        master.config(menu=menubar)
        drawing_utility_run=Drawing_Utility()
        drawing_utility_run.drawer(self.c)

    def Edit_New(self): 
        Export_Poscar = self.Export_Poscar = Toplevel(self.master)
        self.Export_Poscar.title('New Ribbon...')
        self.Export_Poscar.geometry('300x400')
        self.scale_Label= Label(Export_Poscar, width=15, text='scale:')
        self.scale_Label.grid(row=2, column=0)
        self.scale_Label= Label(Export_Poscar, width=15, text='scale:')
        scale_var = StringVar()
        self.scale_Spin= Spinbox(Export_Poscar, from_=1, to=1000, increment=1, width=15, command=self.execute_request_immediate, textvariable=scale_var)
        self.scale_Spin.grid(row=2, column=2)

    def execute_request_immediate(self):
        global scale
        User_Set_Scale=float(self.scale_Spin.get())
        scale=User_Set_Scale
        drawing_utility_run=Drawing_Utility()
        drawing_utility_run.drawer(self.c)

class Drawing_Utility:
    def drawer(self, canvas):
        self.canvas=canvas
        self.canvas.delete('all')
        import Generator #generates my data (imports 'scale' from above where possible)
        Generator_run=Generator.Generator()
        Generator_run.generator_go()        
        from Generator import coordinates_x_comp, coordinates_y_comp #imports necessary lists
        import Processor #Imports coordinates_x_comp, coordinates_y_comp, cleans and analyses
        Process_xy_Data=Processor.Data_Processor()
        Process_xy_Data.Process_Data()
        from Processor import p_1, p_2
        for Line in xrange(len(p_1)):
            self.canvas.create_line(p_1[Line],p_2[Line], fill='red', activefill='blue', width=1)

root=Tk()
run_it_canvas=Interface_On()
run_it_canvas.Interface_Elements(root)
root.mainloop()

1 个答案:

答案 0 :(得分:1)

我不确定这些事情会不会解决你说你正在观察的内存泄漏问题,但我会解决一些可能有帮助的问题:

1。您正在使用本地变量(drawing_utility_run)来存储Drawing_Utility个实例。现在还不完全清楚为什么这些实例在退出时创建它们的方法没有收集垃圾,但不管怎样,似乎你可能希望该对象持久存在,所以你应该将引用存储在实例命名空间中,就像这样:

self.drawing_utility_run=Drawing_Utility()
self.drawing_utility_run.drawer(self.c)

2。当您使用self.canvas.delete('all')删除所有画布对象时,您依赖于Tkinter版本将字符串'all'实现为已识别常量的事实,可能是这种情况,但不能保证。 Canvas.delete函数将接受任何参数,无论它是否代表已识别的常量或标记/ ID,而不会抛出错误 - 例如try self.canvas.delete('blah blah blah')。即你依赖self.canvas.delete('all')删除所有对象,但对我来说这并不明显。使用Tkinter常量ALL代替字符串'all'

3。除非您有充分的理由让导入的模块仅存在于Drawing_Utility实例命名空间中,否则您应该将所有import语句移到模块级命名空间的顶部。

4。您的import语句是多余的:

import Generator #generates my data (imports 'scale' from above where possible)
from Generator import coordinates_x_comp, coordinates_y_comp #imports necessary lists
import Processor #Imports coordinates_x_comp, coordinates_y_comp, cleans and analyses
from Processor import p_1, p_2

您不需要import Generatorfrom Generator import coordinates_x_comp。只需import Generator,然后参考Generator.coordinates_x_comp。通过使用这两个导入语句,您可以双重导入Generator.coordinates_x_compProcessor.p_1等。