parenting directgui controls

I have a directframe on which I’ve put various directentry and directlabel controls.

I’ve parented each one to the frame, which lets me easily hide everything by hiding the frame (It’s a tabbed interface and I have 3 frames).

A couple of questions:

  1. When I destroy() the frame all the controls would be destroyed as well, right?

  2. what if the controls were named as attributes of another object ( the main game class) would that prevent them from being destroyed?

example:

class mygame():

init code ...
screen1


def screen1(self):
	self.frame1 = DirectFrame(etc.....)
	self.cmdNewGame = Direcbutton (text="new game", parent=self.frame1, etc...)

in this example, would self.cmdNewGame still be around after I destroyed self.frame1 (because it’s an atribute of the main game object?)

What If I named it “self.frame1.cmdNewGame” - would that be better? Or is there no difference?

  1. SHould directgui objects be removed with destroy() or clean up and detach (like actors?) I noticed 1 check I’m doing using hasattr tells me that a directframe is still there evn though I used destroy() on it. (could be a ref to it is still around or is destroy() not enough for directgui objects?)

I already asked myself the exact same question and I tested it this way:

import direct.directbase.DirectStart
from direct.gui.OnscreenText import OnscreenText 
from direct.gui.DirectGui import *
from direct.showbase.DirectObject import DirectObject
 
class myGui(DirectObject):
 def __init__(self):
   self.myFrame= DirectFrame(frameSize=(-2,2,-2,2),scale=.3,pos=(-.5,0,0))
   self.myButton= DirectButton(text='destroy fram',parent=self.myFrame,
                               scale=.3,command= self.myButtonCmd)
   self.myText= OnscreenText(text='Test programs are \n good for health',
                             parent=self.myFrame,pos=(0,1),scale=.5)

   self.printButton=DirectButton(text='print',scale=.1,command= self.printCmd,
                                 pos=(.5,0,0))

 def myButtonCmd(self):
   self.myFrame.destroy()

 def printCmd(self):
   print self.myText.getText()

myGui()
run()

Here, after destroying the frame, you can still read OnscreenText which is supposed to be destroyed too!
I finally accepted that objects are destroyed with meaning cleared from memory but the code is still here but I’m maybe wrong.
A more advanced user need to explain what’s going on python side.

I think that the visual representation of it is destroyed, but you haven’t actually deleted it.

I use destroy then delete to get rid of a DirectGui object.

I noticed the hasattr() check I was doing was reporting that a directframe was still an attribute of my gaem object asfter I’d used destroy() - I had to use “del” to get rid of it.

But on another frame I only had to destroy()

the difference between the 2 frames was only that the 1 I had to “del” had other direct controls parented to it.

Any python guru want to add comments on this for newbies like myself? Just wondering how Python is handling this.

Was just wondering on this again.
Is destroy() and a “del” statement necessary to totally eliminate a directgui opject?

destroy() on a DirectGui object will automatically visit all of the child DirectGui objects and call destroy() on them, recursively.

destroy() is therefore necessary on the top frame, but not on child objects. It will remove messenger hooks and remove the geometry from the scene.

del should not be necessary. This is a python construct that removes the binding of the particular variable.

David

Thanks for the reply. What you describe is what I would expect. However hasattrib reports my object still being around after a destroy().

I’ll try to work up a small example. Prioably something I’m doing to the object after I create it.

hasattr() will report whether the Python wrapper still exists. But you would not expect destroy() to remove the Python wrapper. If you really want the Python wrapper to go away, you have to use del.

But usually, there’s no reason to insist that the Python wrapper must go away.

David

ah ok, that explains it. I was using hasattr to check for the object existing. (assume there’s no easier way?)

I’m OK to leave in a del statement in my code so I can use hasattr to do this.

That’s fine. It’s a little bit cleaner to set it to None, rather than deleting it; then you can use something like “if self.myFrame” rather than “if hasattr(self, ‘myFrame’)”, which is both easier to read and probably a tiny bit more efficient.

David