Exiting gApplication

I’m a long-time user of python and ROOT, first time user of PyROOT, and I’m having trouble getting my program to end. Here’s the code, with comments about my understanding of what it does:

import sys
import random

import ROOT

ROOT.gApplication.SetReturnFromRun(0)
##When the ROOT thread terminates, take the python process with it
print ROOT.gApplication.ReturnFromRun()
##Check to make sure the bool is set, result is “0”

hist = ROOT.TH1F(“hist”,“test”,100, 0, 1)
for x in range (1, 1000):
hist.Fill(random.random());
hist.Draw();
##Fill hist & draw

ROOT.gApplication.Run()
##Start the ROOT api thread: roughly equivalent to Tkinter’s .mainloop()
ROOT.gApplication.Terminate(0)
##When the ROOT api thread has finished (e.g. the user
##has selected “Quit ROOT” in the gui), gApplication is deleted
sys.exit(0)
##Force the python process to terminate

What happens is that I get an “automatically generated” canvas with the plot, which I can manipulate as I like. However, the process never terminates. If I try to do “Quit ROOT”, I’m stuck–updating of the canvas gets turned off, but the process doesn’t terminate. Either way, I can’t even out of the process; I have to “kill -9” it from another xterm.

Am I missing a concept here? Or maybe just some keystrokes?

Thanks for the help,
Julie

Julie,

could you please specify which platform and what version of python/ROOT you are using? Point being, your script runs just fine for me (ROOT HEAD CVS, p2.4.3, Linux) and selecting “Quit ROOT” under menu “File” in the created canvas works as expected.

As an aside, python installs handlers for most signals, and collects them. This way, it can implement such translations as SIGINT (^c or +‘c’) -> KeyboardInterrupt exception. If you want to unconditionally kill a python process, SIGQUIT (^\ or +’’) will always forward to the shell, which will then kill python.

Cheers,
Wim

I meant to include this info (even wrote it down on scrap paper):

Linux (looks like kernel 2.4)
Python 2.2.2
ROOT 4.04/02b

It appears they were built with gcc 3.4.2 and 3.4.3, respectively

Thanks for the <^> hint, my two-xterm solution was annoying.

–Julie

[quote=“wlav”]Julie,

could you please specify which platform and what version of python/ROOT you are using? Point being, your script runs just fine for me (ROOT HEAD CVS, p2.4.3, Linux) and selecting “Quit ROOT” under menu “File” in the created canvas works as expected.

As an aside, python installs handlers for most signals, and collects them. This way, it can implement such translations as SIGINT (^c or +‘c’) -> KeyboardInterrupt exception. If you want to unconditionally kill a python process, SIGQUIT (^\ or +’’) will always forward to the shell, which will then kill python.

Cheers,
Wim[/quote]

Julie,

sorry, can’t reproduce it with python 2.2.3, ROOT 4.04/02b, on Linux either. Given that there have been occasions of race conditions between the GUI and the main thread, that could be it, in which case you’re out of luck for that version (several changes have been made since the ROOT version that you are using).

Can I propose something completely different? Something like:[code]import sys, time
import random

import ROOT

open( “PyOnExit.C”, ‘w’ ).write(
""“struct PyOnExit : public TObject {
void OnExit(Int_t) {
TPython::Exec( “import main; main.stillActive = 0” );
}
};
”"" )

ROOT.gROOT.LoadMacro( “PyOnExit.C” )
ROOT.gApplication.Connect( “Terminate(Int_t)”, “PyOnExit”, 0, “OnExit(Int_t)” );

hist = ROOT.TH1F(“hist”,“test”,100, 0, 1)
for x in range (1, 1000):
hist.Fill(random.random());
hist.Draw();

stillActive = 1
while stillActive:
try:
time.sleep( 1 )
except (SystemExit,KeyboardInterrupt):
sys.exit(0)
[/code]

Also, you could extend this, by implementing an OnClosed() in the same way in OnPyExit, and Connect it to the “Closed()” of your main canvas. That way, if the main canvas is closed (not through “Quit ROOT”, but e.g. by clicking the close button “X”), you quit the application.

Note that this approach also solves the ^c pb, as well as main thread kills from subthreads (not possible in p2.2, but p2.3 offers it).

HTH,
Wim

Thanks for the ideas. Unfortunately, it doesn’t quite work with my setup, which I am kind of stuck with. I guess I’m going to what I have done before: skip PyROOT by compiling the ROOT portion of my code and calling it through Python’s os.system() call. Thanks though.

Julie