Crash using TRootEmbeddedCanvas

Hello everyone,

I’m seeing a crash with python 2.5.2 with ROOT 5.20/00, when trying to create a gui containing a TRootEmbeddedCanvas.

In short : creating 2 instances of a gui containing a TRootEmbeddedCanvas causes a crash.

gui_pyroot> python -i
LArGui : thread =  -1208944448 self=  <ROOT.TGMainFrame object ("fMainFrame2") at 0x8b8d0c8>
emb canvas =  <ROOT.TRootEmbeddedCanvas object ("fRootEmbeddedCanvas4") at 0x8bbee08>
LArGui : thread =  -1208944448 self=  <ROOT.TGMainFrame object ("fMainFrame16") at 0x8c28560>
emb canvas =  <ROOT.TRootEmbeddedCanvas object ("fRootEmbeddedCanvas18") at 0x8c28710>
>>> Error in <RootX11ErrorHandler>: BadDrawable (invalid Pixmap or Window parameter) (TGCompositeFrame XID: 37748995, XREQ: 62)
TGCompositeFrame:	37748995
	TGViewPort:	37748969
	TRootEmbeddedCanvas:	37748968
	TGVerticalFrame:	37748967
	TGVerticalFrame:	37749002
	TGMainFrame:	37749001

After that the program hangs and I have to kill it manually.

The code in is simply :

import ROOT
import thread

class builder:
    def __init__(self):
        self.gui = None
    def build(self):
        self.gui = MyGui(ROOT.gClient.GetRoot())

b = builder()

class MyGui(ROOT.TGMainFrame):
    def __init__(self, p):
        print 'LArGui : thread = ', thread.get_ident(), 'self= ',self

    def init_gui(self):

        self.ChangeOptions( self.GetOptions() | ROOT.kVerticalFrame)        

        # main vertical frame
        self.mvert = ROOT.TGVerticalFrame(self,300,300, ROOT.kFitWidth| ROOT.kFitHeight)

        self.canvas = ROOT.TRootEmbeddedCanvas("Ecanvas",self.mvert,200,200)
        print 'emb canvas = ', self.canvas
        self.mvert.AddFrame( self.canvas,ROOT.TGLayoutHints(ROOT.kLHintsTop | ROOT.kLHintsExpandX| ROOT.kLHintsExpandY))

        self.AddFrame(self.mvert, ROOT.TGLayoutHints(ROOT.kLHintsTop | ROOT.kLHintsExpandX | ROOT.kLHintsExpandY))


Actually I don’t see a crash if I keep the different python instance of the gui alive in a list. But I’d like to advoid that, if possible…

Do you want to keep the original window alive and create a second one, or do you want to cleanly destroy the old one and subsequently create another one?

If it is all just a matter of “not crashing” then you’ll need to manually remove the old canvas from the gROOT list of canvases (dunno why; might just be timing). Something like this: def build(self): if ( self.gui ): ROOT.gROOT.GetListOfCanvases().Remove( self.gui.canvas.GetCanvas() ) self.gui = None self.gui = MyGui(ROOT.gClient.GetRoot()) self.gui.init_gui() appears to do the trick for me.



I want to cleanly destroy old instances. So I’ll use your trick when needed.

thanks a lot for your help.