Closing Gui Application crash

Hey All!

I am quite new to rootTalk, and have searched the forum for my problem and did not find anything equal. Hope, i am right here.
So:

I have a crash when i want to quit my gui with pyROOT, which i don’t understand. If someone could help me or show a workaround, that would be great :slight_smile:

I work on the following conditions:

Scientifix Linux 6.5 (Carbon) with GNOME 2.28.2
Python 2.6.6
ROOT 5.34/17

I post a minimal example and the entire stack trace in attachment:

import ROOT

if __name__ == "__main__":
    window = ROOT.TGMainFrame(ROOT.gClient.GetRoot())
    quitButton = ROOT.TGTextButton( window, "quit") 
    window.AddFrame(quitButton)
    window.MapSubwindows()
    window.Resize( window.GetDefaultSize() )
    window.MapWindow()
    def test(window):
        print "TEST"
        window.Cleanup()
    quitButton.Connect("Clicked()", "TPyDispatcher", ROOT.TPyDispatcher(lambda : test(window)), "Dispatch()")
    raw_input("Press Enter to quit\n")

Thanks alot, cheers
Daniel
stack-trace.txt (6 KB)
minimalExample.py (492 Bytes)

Hi,

python uses reference counting, so you have to make sure that you keep references outstanding to any objects that you wish to reference in the future. The worst is probably “ROOT.TPyDispatcher(lambda : test(self))” which in your code disappears after the Connect() call. But especially during cleanup, you have to make sure the order is the way you want it: you are destroying the window while you’re working with it.

A simple way of dealing with the order, is to make all graphics parents have references to their graphics children, and then let python deal with the cleanup the normal way. See $ROOTSYS/tutorials/pyroot/gui_ex.py for an example.

HTH,
Wim

Dear Wim!

Thanks A LOT for your fast answer. I have to admit, i dont totaly understand everything.

[quote=“wlav”]Hi,

python uses reference counting, so you have to make sure that you keep references outstanding to any objects that you wish to reference in the future. The worst is probably “ROOT.TPyDispatcher(lambda : test(self))” which in your code disappears after the Connect() call. But especially during cleanup, you have to make sure the order is the way you want it: you are destroying the window while you’re working with it.

[/quote]
Why is the reference lost in my case? I thought, that the methode test is only executed when i press the button, so that would be ok for me, if the reference counter is 0 afterwards… Indeed it is my purpose. But i bet i don’t quite understand it.

[quote=“wlav”]

A simple way of dealing with the order, is to make all graphics parents have references to their graphics children, and then let python deal with the cleanup the normal way. See $ROOTSYS/tutorials/pyroot/gui_ex.py for an example.

HTH,
Wim[/quote]

I tested this and have two problems (never open one door… more will open :slight_smile:):

1):
First i do not want to kill python afterwards, i just want to exit the gui.
The ExitButton.SetCommand( 'TPython::Exec( "raise SystemExit" )' ) seems to be the central point of the solution in $ROOTSYS/tutorials/pyroot/gui_ex.py. So is there any alternative to this which would only delete the gui and go on in python?

2):
With the example in $ROOTSYS/tutorials/pyroot/gui_ex.py i get no crash, but my terminal behaves strangely afterwards. I.e. i can not recall old commands or rather can not see them and other graphical stuff. The only thing i changed was adding a raw_input() in order to keep the gui open.

Many thanks again :exclamation: , yours
Daniel

Daniel,

[quote=“dboeckenhoff”]Why is the reference lost in my case? I thought, that the methode test is only executed when i press the button[/quote]This call is the problem one:quitButton.Connect("Clicked()", "TPyDispatcher", ROOT.TPyDispatcher(lambda : test(window)), "Dispatch()")as after that, the TPyDispatcher will be gone. It is called when setting up the window, not when the button is pressed. The lambda is theoretically fine, as it will bind the window, but it’s not fine to call Cleanup in there: that should be done when the window goes away (is why it’s in del).

Then call CloseWindow: self.ExitButton = ROOT.TGTextButton( self.ButtonsFrame, '&Exit', 20 ) self.ExitButton._dispatcher = ROOT.TPyDispatcher(self.CloseWindow) self.ExitButton.Connect( 'Clicked()', "TPyDispatcher", self.ExitButton._dispatcher, 'Dispatch()' ) self.ButtonsFrame.AddFrame( self.ExitButton, ROOT.TGLayoutHints() )

[quote=“dboeckenhoff”]but my terminal behaves strangely afterwards. I.e. i can not recall old commands or rather can not see them and other graphical stuff. The only thing i changed was adding a raw_input() in order to keep the gui open.[/quote]Which terminal? The shell or the python interpreter? If the interpreter: the python interpreter will not have any history loaded as it is not started in interactive mode (you can load it explicitly, though). If the shell: that’s more likely caused by a crash in an earlier session. Reset the tty with stty sane (use ^j for ‘return’ if you see ‘^M’ when hitting the actual return button).

Cheers,
Wim

T H A N K S
Problem solved,- It’s amazing, how you help people without having any benefit yourself. By the way - it was the bash, but it works fine now with this solution. Cheers,

Daniel