Enforcing canvas to stay visible and not be dereferenced


I want to create a process that would show to a user results of analysis.
My application is independent from ROOT and the only place I want to use it is in additional process.

I’ve written the following code and I’m not able to enforce a canvas to stay visible Somehow it gets dereferenced almost immediately. I’ve been trying different thing like disabling garbage collector and setting ownership to False but the canvas still disappears almost immediately.

NOTE: This is not the final production code, but its simplified version.
NOTE2: I’ve added a sleep command, if the process goes into sleep everything is fine, however when it reaches the while loop canv1 disappears and is dereferenced.

[code]def show_me_canvas(file_name):
import ROOT
import time
import gc
file_ = ROOT.TFile(file_name)
ROOT.SetOwnership(file_, False)
canv1 = ROOT.TCanvas()
ROOT.SetOwnership(canv1, False)
ROOT.gDirectory.GetObject(“c1;1”, canv1)
print “Canv1 status befor while loop:”, canv1
while canv1:
print “Canv1 status in while loop:”, canv1
print "Sleeping…"

if name == “main”:
from multiprocessing import Process
proc1 = Process(target=show_me_canvas, args=((“c1.root”,)) )


what is this line for: ROOT.gDirectory.GetObject("c1;1", canv1)
If it works, it doesn’t do anything, if it fails, canv1 will be set to zero?


Hi Wim.

Thank you for you answer.
What do you mean by: “if it works it doesn’t do anything”?
I need to somehow load the histogram into my application’s memory, right?
Isn’t it the way?

  1. Opening a file.
  2. Creating a canvas.
  3. Getting a canvas object from the file to my memory.
  4. Showing the canvas.



the point I’m missing is what 3) does. That may be my lack of knowledge on how to work with TCanvas’s. However, I do know what GetObject() does to the canv1 variable: it takes it by reference to pointer and will reset the internal pointer of canv1, thereby removing the old. If you want a NULL pointer to a TCanvas for use with GetObject(), use canv2 = ROOT.MakeNullPointer(ROOT.TCanvas) and pass that.


Dear Wim,

You are right, that was a monkey patch because I couldn’t create a canvas variable “on the fly”.
That’s the way I should’ve taken.

Nevertheless it still doesn’t solve my main problem, because now my while loop iterates forever.
Is there a way to detect that the user closed canvas? I would need to catch it in order to end the process and the script.



presumably a callback through CINT’s signal/slot needs to be setup. Some examples (for buttons, but I guess for the “quit” coming from closing the canvas it should be possible, too) are in $ROOTSYS/tutorials/pyroot/gui_ex.py .