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?
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
(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:
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?
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.