Live updating histos using drag and drop


I’m trying to modify the example $ROOTSYS/tutorials/gui/drag_and_drop.C to make an online histogram plotter. Essentially for now all I want to do is use this example as it is, but have the histograms displayed (e.g. those that have been dragged and dropped onto the canvas) automatically update on the canvas as they are changed (e.g. filled).

I have used a TTimer to update to the histos and update the canvas, but the histograms on the canvas do not update unless I re-drag and drop them. So my question is; how do I get these dragged and drop histos to update as they are filled (when a timer TimeOut is called) ?

In previous systems (without drag and drop) I’ve called histo->Draw() every TimeOut prior to canvas->Update(), but now because of the drag and drop I don’t have a pointer to the current histo displayed in the canvas (or one of the pads in the canvas). Is there a way to get the object a canvas is displaying?

Many thanks in advance,

You can, for example, request a list of primitives from your canvas and scan it for a histogram.

void find_hist()
if (!gPad) {
std::cout<<“gPad is null\n”;

const TList * const objects = gPad->GetListOfPrimitives();

//If you work with ROOT 5/CINT:
TIter next(objects);
const TObject * obj = 0;
while (obj = next())
if (obj->InheritsFrom(“TH1”))
std::cout<<"Found a histogram: "<IsA()->GetName()<<std::endl;

//Or, with ROOT 6/or ACLiC and C++11:
while (const auto obj = next()) {
if (const auto hist = dynamic_cast<const TH1 *>(obj))
std::cout<<"Found a histogram: "<IsA()->GetName()<<std::endl;

Thanks very much for your response. Using your examople I am now able to find the histograms that I have drag and dropped into the pads.

However, anything I try to do with the histo pointer I get from the pad doesn’t seem to change anything (e.g. Fill, Draw etc). I have removed all the “const” statements from your example to try to eliminate const pointers as a possible problem, but still no luck. Any ideas on how to solve this problem?

Even if I change the name of the hist using the original pointer, the pointer from find_hist() still gives the original name, but when I drag and drop again the newly displayed hist returns the new name from find_hist().


Yes, indeed - if you call a non-const member function (like Fill, SetBinContent, etc.) on a histogram object, you have to remove const qualifiers. To update a cavas after you’ve updated your histogram - call canvas->Modified(); canvas->Update();

Thanks again for your quick response. Following your advice I can now see the full problem. The issue is not with const pointers, but instead that the histo in the canvas (from drag and drop) is a copy of the hist I drop there (it has the same name, but a different pointer address). So the pointer to the hist I get back from find_hist() is to the copy drag and drop makes, not the original histo. This is why modifiying the original histo did not cause updates in the displayed histo.

I can modify the displayed histo (the copy) and using canvas modified/update this then updates as I wish. However, these modifications don’t affect the original histo of course.

Does anyone know a way to make the drag and drop mechanism draw the original histo to the canvas, rather than making a copy? In the example I have based my code on the drag and drop handling is done by seeting the embedded canvas as the DND target (SetDNDTarget) and the histo TGListTreeItems as DND sources (SetDNDSource).