0

以下のコードでメモリ リークが発生しています。別々のモジュールでデータを作成および処理していますが、これは私が見ることができるリークの原因ではありません。この問題を修正する方法はわかりませんが、縮尺を変更するたびに描画クラスの新しいインスタンスを呼び出しているためだと思います。このスレッドを読みましたが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()
4

1 に答える 1

1

これらのいずれかが、あなたが観察していると言ったメモリリークを修正するかどうかはわかりませんが、私が修正したい問題がいくつかあります。

1.インスタンスdrawing_utility_runを格納するためにローカル変数 ( ) を使用しています。Drawing_Utilityこれらのインスタンスが作成されたメソッドが終了した後でガベージ コレクションが行われない理由は完全には明らかではありませんが、いずれにせよ、オブジェクトを永続化する必要があるように思われるため、次のように参照をインスタンスの名前空間に保存する必要があります。 :

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

2. すべてのキャンバス オブジェクトを削除すると、Tkinter バージョンが文字列を認識された定数としてself.canvas.delete('all')実装しているという事実に依存しています。これは事実である可能性がありますが、保証されていません。'all'このCanvas.delete関数は、認識された定数またはタグ/ID を表しているかどうかに関係なく、エラーをスローすることなく、任意の引数を受け入れます (たとえば、 try ) self.canvas.delete('blah blah blah')。つまり、すべてのオブジェクトを削除しようself.canvas.delete('all')としていますが、それがそうであることは私には明らかではありません。string の代わりに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 Generatorと の両方を行う必要はありませんfrom Generator import coordinates_x_compimport Generatorを参照してくださいGenerator.coordinates_x_compGenerator.coordinates_x_comp両方の import ステートメントを使用すると、二重インポートProcessor.p_1などになります。

于 2013-10-06T22:59:55.807 に答える