inheritance from Tkinter == leaks. true?

Fragen zu Tkinter.
Antworten
kac
User
Beiträge: 3
Registriert: Dienstag 30. Oktober 2007, 22:40

Dienstag 30. Oktober 2007, 23:27

Hello everybody
I've just started playing with Pyhon( circ. 1 month).
And need Your help.
With so nice and productive language, builded application with GUI based on Tkinter. Its almost done but... wanted to check resources usage and found huge memory leaks. Its about classes ingerted from Tkinter classes.
Eg. when i create an object from Frame:

Code: Alles auswählen

class my_frame( Tkinter.Frame ):
   def __init__( self, master=None )
      Tkinter.Frame.__init__( self, master )
      self.but = Tkinter.Button( master=self ) 
      self.but.grid()
after 'my_class.destroy()' and 'my_class=Null' the garbage collection stores 'my_class', 'button' and some dictionaries and never throw them away.
if i define it like this

Code: Alles auswählen

class my_frame( Tkinter.Frame ):
   def __init__( self, master=None )
      Tkinter.Frame.__init__( self, master )
      but = Tkinter.Button( master=self ) wyczyszczony
      but.grid()
after destroy() and overwriting referenced name all is cleaned up.
I've worked it around by:

Code: Alles auswählen

class my_class ():
   def __init__(self, master=None):
      self.frame = Frame( master )
      self.but = Button( self.frame )
      self.but.grid()
   def grid( self, **opt ):
      self.frame.grid( opt )
   def destroy( self ):
      self.frame.destroy()
and now after any number of creating/destroying that object there are no aditional garbage.
Is this version(Python2.5)/platform(fedora7,win32) issue or it's my way of using Tkinter? Or bug?
On Polish board i've no replies for that. And time is running.
Or the best way is to switch to wx or something else( to witch it will be simplest for me?)
Sorry that in En. Sorry that this En is so poor.
Zuletzt geändert von kac am Dienstag 30. Oktober 2007, 23:36, insgesamt 3-mal geändert.
BlackJack

Dienstag 30. Oktober 2007, 23:32

Sorry but I find it hard to follow what you are actually doing there, what you want and what you get.

Could you please give a self contained example and formatted in a way that preserves the indention? (code tags)
kac
User
Beiträge: 3
Registriert: Dienstag 30. Oktober 2007, 22:40

Mittwoch 31. Oktober 2007, 00:05

ok its may be like that:

Code: Alles auswählen

#!/usr/bin/env python

import gc

from Tkinter import *

class my_frame_leak( Frame ):
   def __init__( self, master=None):
    self.master = master
    Frame.__init__(self, master )
    self.but = Button( self,text="destroy",command=self.master.destroy )
    self.but.grid()

class my_frame_good( Frame ):
   def __init__( self, master=None):
    self.master = master
    Frame.__init__(self, master )
    but = Button( self,text="destroy",command=self.master.destroy )
    but.grid()

class my_frame_fix(  ):
   def __init__( self, master=None):
    self.master = master
    self.frame = Frame( master )
    self.but = Button( self.frame ,text="destroy",command=self.master.destroy )
    self.but.grid()

   def destroy( self ):
    return self.frame.destroy()

   def grid( self, **opt ):
    return self.frame.grid( opt )


while 1:
	root = Tk()
	my = my_frame_leak( root )#or my_frame_good or my_frame_fix
	my.grid()
	root.mainloop()
	print "objects count:%d" %len(gc.get_objects())
my_frame_leak simple leaks ;)
my_frame_good and my_frame_fix after number of recreatings don't leave any garbage.
+++++++++++++++++++++++
my_frame_leak cumulate garbages with last recreate and its growing very fast( its True for Toplevels and Buttons, maybe Canvas. With an array of buttons few destroys give us 10MB). And in my_frame_fix list of widgets left garbage too. But dictionary of widgets doesn't left any.
BlackJack

Mittwoch 31. Oktober 2007, 09:10

It's not really leaking:

Code: Alles auswählen

objects count:5048
objects count:5057
objects count:5066
...
objects count:5795
objects count:5804
objects count:5813
objects count:5066
objects count:5075
You are creating cycles between the objects so it takes some time until the garbage collecter comes around and frees them.
kac
User
Beiträge: 3
Registriert: Dienstag 30. Oktober 2007, 22:40

Mittwoch 31. Oktober 2007, 18:16

now.. please don't laugh at me
I have my own sword in my stomach

Code: Alles auswählen

import gc
from Tkinter import *
gc.set_debug(gc.DEBUG_LEAK)

class my_frame_leak( Frame ):
   def __init__( self, master=None):
        Frame.__init__(self, master )
        self.but = Button( self, text="quit", command=quit )
        self.but.grid()

while 1:
        root = Tk()
        my = my_frame_leak( root )#or my_frame_good or my_frame_fix
        my.grid()
        root.mainloop()
        gc.collect()
        print "objects count:%d" %len(gc.get_objects())
guess what! The accumulation is from 'gc.set_debug(gc.DEBUG_LEAK)'.
Yes, You're right, it doesn't leak.
And World is beautiful once more:)
And I love Python even more then after 'hello world'
When working in 'C' with microcontrollers it's hard to even think about something like gc, and that its working so fine.
Thanks for Your reply, time and for this board
Antworten