Retrieving TLegend

Hi ROOTers,
I am looking a way to retrieve my TLegend object and just created when calling

TPad::BuildLegend()

However, what is the name of it?
Is the TLegend object added to the list of primitives in the canvas it was drawn?

I have a pointer to the canvas, I know there is a TLegend but I am not sure how to retrieve it, as for example, to delete and create a new one.

Thanks,

Seriously, who owns the TLegend object created by TPad::BuildLegend()?

I tried the following:

TLegend* mycLeg=myc->BuildLegend();
mycLeg->SetName("mycLeg");

and then

 TLegend* pave=(TLegend*)myc->FindObject("mycLeg");
if(pave) 
    delete pave;

I am assuming that the TPave::SetName() overrides the TObject::SetName() function and I am (naively) assuming that “mycLeg” is being owned by the cnavas object is was drawn. What am I doing wrong?

Thanks,

The legend is drawn in the current pad. See
root.cern.ch/root/html/src/TPad.cxx.html#Bsw1XE
So it is own by this pad.
Can you send a small running script reproducing your problem ?

Hi
No, there is no problem with the TLegend… The issue I was having is that after I call TPad::BuildLegend() everything works fine until… Well, if I want to remove the TLegend created (Let’s assume I redraw/added more graphs into the current pad, then I just want to call BuildLegend() again) I do not know how to get my hands on this object using standards ways, as for example, FindObject(char* name), since I do not know the name of the object.

I guess I could iterate through the ListOfPrimitives of the TPad and look for a *TLegend object. Right now, I found a solution to my task. I am calling mycanvas->Clear() which removes all the current objects (including the TLegend) and then I redraw everything again.

Looking at the source code, I notice` TLegend inherits from TPave and it is TPave eventually inherits from TObject which mean this object should have a name.
I tried setting the name

TLegend* myleg=myc->BuildLegend();
myleg->SetName("leggy");

When when I tried to retrieve from the current canvas (where it was created) it it did not work. It should work, right?
Cheers,

Yes. Do gPad->ls() and you will see the legend. Like any other object in the pad.

(yes, I’m aware that this is an old thread but since the related topic is still current and the info here may be wrong…)

[quote=“couet”]The legend is drawn in the current pad. See
root.cern.ch/root/html/src/TPad.cxx.html#Bsw1XE
So it is own by this pad.[/quote]
I recently wondered the same question as cmosquer and to me it seems that the answer is that the caller owns the returned TLegend (or in practice since it’s undocumented it probably leaks in majority of cases). The returned object does not have kCanDelete-bit set nor a breakpoint in TLegend destructor triggers in the following example program (tested with ROOT 5.34.3, VC2010)

int main(int argc, char **argv)
{
	TApplication app("testapp", argc, argv);
	{
		TCanvas canvas;
		canvas.cd();
		auto pTf1 = new TF1("a", "sin(x)", -1, 1);
		pTf1->SetBit(kCanDelete);
		pTf1->Draw();
		TLegend* pLegend = canvas.BuildLegend();
		const bool b = pLegend->TestBit(kCanDelete); // Returns false
		//pLegend->SetBit(kCanDelete); // Uncommenting this causes breakpoint at ~TLegend to trigger at end of scope.
	}
	return 0;
}

Unless I need to be corrected here, could you please document this in TPad::BuildLegend; simply changing the kCanDelete-bit in the returned TLegend could break existing apps.

As a sidenote, in order to add the legend in current pad, the code in TPad::BuildLegend currently does:

TVirtualPad *gpadsave;
gpadsave = gPad;
this->cd();
leg->Draw();
gpadsave->cd();

I got curious why that has to go through all that trouble and changing global variables instead of simply having a “draw primitive on given pad” function to call?

Could you provide patch file with the changes you suggest ?

For the documentation mention a patch seems like a overkill. For the other part the idea was simply to have a function like leg->DrawOnPad(this), which would do what’s intended clearly and without redundant side effects. But since that is likely to involve (minor) refactoring in TPad and TObject, it would be better done with some more thinking.

Ok, doc is updated.