Re: [ROOT] Re: GUI classes and X11 errors

From: Fons Rademakers (Fons.Rademakers@cern.ch)
Date: Fri Sep 08 2000 - 01:00:58 MEST


Hi Greg,

  you should delete all the widgets you create in the destructor of 
the window. However, there is no need to keep track of each widget by
named pointer. This is only needed for the ones you want to use later.
What I normally do is something like:

class MyWindow : public TGCompositeFrame {

TList *fTrash;
...
};

MyWindow::MyWindow() : ....
{
   fTrash = new TList;
   TGButton *b = new TGButton(...);
   TGLayoutHints *lo = new TGLayoutHints(...);
   AddFrame(b, lo);
   fTrash->Add(b);
   fTrash->Add(lo);
   b = new TGButton(...);
   AddFrame(b, lo);
   fTrash->Add(b);
   ...
}
MyWindow::~MyWindow()
{
   fTrash->Delete();
   delete fTrash;
}

Where fTrash is a simple collection of all widgets to be deleted.

Cheers, Fons.
 
   
On Thu, Sep 07, 2000 at 10:09:54AM -0400, Greg Novak wrote:
> I apologize about the previous posting; these are the files I meant to
> send.
> 
> Thanks,
> Greg
> 
> On Thu, 7 Sep 2000, Greg Novak wrote:
> 
> > I'm writing an application that uses the Root GUI classes, TG*, and I'm
> > using Root 2.23/12 on a machine running Red Hat 6.1. 
> > 
> > I have one window where a button performs a long computation and then
> > deletes the window itself.  I have found that if I place another window
> > over certain widgets while the computation is running (so that they need
> > to be redrawn), then I get errors like the following when the window tries
> > to delete itself:
> > 
> > Error in <RootX11ErrorHandler>: BadDrawable (invalid Pixmap or Window 
> > parameter) (XID: 54526074)
> > 
> > It seels that what's causing this problem are two TGLabel objects.  I
> > never need them after I put them in the window, so I didn't bother to keep
> > a pointer to them.  Do I need, instead, to keep a pointer to every GUI
> > object I create and then delete them in a particular order?
> > 
> > Also, what is the memory management paradigm for these classes?  Looking
> > at the guitest.cxx example, it seems that I only have to give names to
> > object I need to access later (TGTextEntry objects for instance, where I
> > need to call GetText() to get the string a user entered).  I assume, then,
> > that when I create a widget and add it to a window, the window then frees
> > the widget's memory when the window is destroyed.  Is this correct?
> > 
> > I've attached the offending code, stripped of unimportant details.  The
> > main part I've left intact is the object construction/destruction.
> > 
> > Thanks!
> > Greg
> > 

> 
> ProcessFileDialog::ProcessFileDialog(const TGWindow *p, 
> 				     const TGWindow *main, UInt_t w,
> 				     UInt_t h, UInt_t options)
>   : TGTransientFrame(p, main, w, h, options)
> {
>   // layouts
>   topLeftLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft | 
> 				    kLHintsExpandX, 2, 2, 2, 2);
>   centerLayout = new TGLayoutHints(kLHintsCenterX | kLHintsCenterY,
> 					2, 2, 2, 2); 
>   bottomRightLayout = new TGLayoutHints(kLHintsBottom | kLHintsRight,
> 					2, 2, 2, 2);
>   // end layouts
> 
>   mainFrame = new TGVerticalFrame(this, 60, 20);  {
>     configTab = new TGTab(mainFrame,300,300); {
>       TGCompositeFrame *tab;
>       tab = configTab->AddTab("Files"); {
> 	inBrowseButton = new TGTextButton(tab, "Browse", B_PROCESS_FILE_IN_BROWSE);
> 	inBrowseButton->Associate(this);
> 	outBrowseButton = new TGTextButton(tab, "Browse", B_PROCESS_FILE_OUT_BROWSE);
> 	outBrowseButton->Associate(this);
>         inFileText = new TGTextEntry(tab, "", TE_PROCESS_FILE_IN);
> 	inFileText->Resize(250, inFileText->GetDefaultHeight());
> 	inFileText->Associate(this);
>         outFileText = new TGTextEntry(tab, "", TE_PROCESS_FILE_OUT);
> 	outFileText->Resize(250, outFileText->GetDefaultHeight());
> 	outFileText->Associate(this);	
> 	splitTreeCheck = new TGCheckButton(tab, "");
> 	if (splitTree==true)
> 	  splitTreeCheck->SetState(kButtonDown);
> 	else
> 	  splitTreeCheck->SetState(kButtonUp);
> 
> 	tab->SetLayoutManager(new TGMatrixLayout(tab, 0, 3, 10));
> 	tab->AddFrame(new TGLabel (tab, "Input File"), topLeftLayout);
> 	tab->AddFrame(inFileText, topLeftLayout);
> 	tab->AddFrame(inBrowseButton, topLeftLayout);
> 	tab->AddFrame(new TGLabel (tab, "Output File"));
> 	tab->AddFrame(outFileText, topLeftLayout);
> 	tab->AddFrame(outBrowseButton, topLeftLayout);
> 	tab->AddFrame(new TGLabel (tab, "Split Tree"), topLeftLayout);
> 	tab->AddFrame(splitTreeCheck, topLeftLayout);	
>       }
>       tab = configTab->AddTab("Trackfitting"); 
>       trackFinder->MakePanel(tab);
>       tab = configTab->AddTab("Geometry");
>       theDetector->MakePanel(tab);
>     }
>     buttonFrame = new TGHorizontalFrame(this, 60, 20, kFixedWidth); {
>       okButton = new TGTextButton(buttonFrame, "&Ok", B_PROCESS_FILE_OK);
>       okButton->Associate(this);
>       cancelButton = new TGTextButton(buttonFrame, "&Cancel", 
> 				      B_PROCESS_FILE_CANCEL);
>       cancelButton->Associate(this);
>       buttonFrame->AddFrame(okButton, topLeftLayout);
>       buttonFrame->AddFrame(cancelButton, topLeftLayout);
>       buttonFrame->Resize(150, okButton->GetDefaultHeight());
>     }
>     mainFrame->AddFrame(configTab, topLeftLayout);
>     mainFrame->AddFrame(buttonFrame, bottomRightLayout);
>   }
>   
>   AddFrame(mainFrame, topLeftLayout);
>   SetWindowName("Process File");
>   Resize(GetDefaultSize());
>   MapSubwindows();
>   MapWindow();
> }
> 
> ProcessFileDialog::~ProcessFileDialog()
> { 
>   delete topLeftLayout; delete centerLayout; delete bottomRightLayout;
>   delete inBrowseButton; delete outBrowseButton;
>   delete inFileText; delete outFileText;
>   delete splitTreeCheck;
>   delete okButton; delete cancelButton;
>   delete configTab;
>   delete mainFrame; delete buttonFrame;
> 
> }
> 
> void ProcessFileDialog::CloseWindow()
> {
>   // Called when window is closed via the window manager.
>   delete this;
> }
> 

> class ProcessFileDialog : public TGTransientFrame {
> private:
>   TString *inFilename, *outFilename;
>   TGLayoutHints *topLeftLayout, *centerLayout, *bottomRightLayout;
>   TGCompositeFrame *mainFrame, *buttonFrame;
>   TGTab *configTab;
>   TGTextButton *okButton, *cancelButton;
> 
>   // stuff for the input/output filename tab
>   TGTextButton *inBrowseButton, *outBrowseButton;
>   TGTextEntry *inFileText, *outFileText;
>   TGCheckButton *splitTreeCheck;
> 
> public:
>   ProcessFileDialog(const TGWindow *p, const TGWindow *main, UInt_t w, 
> 		    UInt_t h, UInt_t options = kMainFrame | kVerticalFrame);
>   virtual ~ProcessFileDialog();
>   virtual void CloseWindow();
>   virtual Bool_t ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2);
> };
> 


-- 
Org:    CERN, European Laboratory for Particle Physics.
Mail:   1211 Geneve 23, Switzerland
E-Mail: Fons.Rademakers@cern.ch              Phone: +41 22 7679248
WWW:    http://root.cern.ch/~rdm/            Fax:   +41 22 7677910



This archive was generated by hypermail 2b29 : Tue Jan 02 2001 - 11:50:32 MET