Launching a new app on current app exit

I have a wxPython App that when it exits launches a diff python App
which segfaults on *nix.

I have narrowed the issue down to loading wx.media.MediaCtrl in the
second app which I find strange because if I launch that app by itself
(not via the 1st app) it runs fine. I have made a small demo that
shows the error

How to replicate
launch example.py then close the frame. What should happen is a second
frame comes up, but it segfaults

Try launching example1.py to see that the app does indeed work if
launched on it's own

example.py (862 Bytes)

example1.py (1021 Bytes)

Works fine on Windows XP SP2, Python 2.4.2, wxPython 2.8.1.1.

Did you try to put the code to run the second app after the call to the first app's MainLoop? Conceptually you should never have two wx.App objects alive at the same time, even during OnExit.

I mean something like this:

if __name__ == "__main__":
     app = BlankApp(0)
     app.MainLoop()
     del app

     import example1
     app = example1.BlankApp(0)
     app.MainLoop()

Dj Gilcrease wrote:

···

I have a wxPython App that when it exits launches a diff python App
which segfaults on *nix.

I have narrowed the issue down to loading wx.media.MediaCtrl in the
second app which I find strange because if I launch that app by itself
(not via the 1st app) it runs fine. I have made a small demo that
shows the error

How to replicate
launch example.py then close the frame. What should happen is a second
frame comes up, but it segfaults

Try launching example1.py to see that the app does indeed work if
launched on it's own

------------------------------------------------------------------------

import wxversion
wxversion.select(["2.8"])
import wx

class BlankFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="App Launch error example")

        self.Freeze()
        sizer = wx.BoxSizer(wx.VERTICAL)

        self.textctrl = wx.TextCtrl(self, wx.ID_ANY, style=wx.TE_MULTILINE)
        sizer.Add(self.textctrl, 1, wx.EXPAND)

        self.textctrl.SetValue("This is App 1")

        self.SetSizer(sizer)
        self.SetAutoLayout(True)
        self.Layout()
        self.Thaw()

class BlankApp(wx.App):
    def OnInit(self):
        self.frame = BlankFrame()
        self.frame.Show()
        self.SetTopWindow(self.frame)

        return True

    def OnExit(self):
        import example1
        app = example1.BlankApp(0)
        app.MainLoop()

if __name__ == "__main__":
    app = BlankApp(0)
    app.MainLoop()

------------------------------------------------------------------------

import wxversion
wxversion.select(["2.8"])
import wx
import wx.media

class BlankFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="App Launch error example")

        self.Freeze()
        sizer = wx.BoxSizer(wx.VERTICAL)

        self.textctrl = wx.TextCtrl(self, wx.ID_ANY, style=wx.TE_MULTILINE)
        sizer.Add(self.textctrl, 1, wx.EXPAND)

        self.textctrl.SetValue("This is App 2")

        #This Segfaults on *nix if loaded via example.py but not if loaded on it's own
        try:
            self.mc = wx.media.MediaCtrl(self, style=wx.SIMPLE_BORDER)
            self.mc.Hide()
        except Exception, e:
            print e

        self.SetSizer(sizer)
        self.SetAutoLayout(True)
        self.Layout()
        self.Thaw()

class BlankApp(wx.App):
    def OnInit(self):
        self.frame = BlankFrame()
        self.frame.Show()
        self.SetTopWindow(self.frame)

        return True

if __name__ == "__main__":
    app = BlankApp(0)
    app.MainLoop()

------------------------------------------------------------------------

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwidgets.org
For additional commands, e-mail: wxPython-users-help@lists.wxwidgets.org

Ya it works fine for me on Win32 as well, but Segfaults on *nix, even
the way you have it insted of in the OnExit code

···

On 2/10/07, Eli Golovinsky <gooli@tuzig.com> wrote:

Works fine on Windows XP SP2, Python 2.4.2, wxPython 2.8.1.1.

Did you try to put the code to run the second app after the call to the
first app's MainLoop? Conceptually you should never have two wx.App
objects alive at the same time, even during OnExit.

I mean something like this:

if __name__ == "__main__":
     app = BlankApp(0)
     app.MainLoop()
     del app

     import example1
     app = example1.BlankApp(0)
     app.MainLoop()

When all else fails, I usually compile Python and wxPython with debug information and run it in a debugger. Gdb should be enough to pin-point the place where the segfault happens.

You can also try to work around the problem by running the second app in a new process using os.execl like so:

if __name__ == "__main__":
     app = BlankApp(0)
     app.MainLoop()

     import os
     import sys
     os.execl(sys.executable, sys.executable, "example1.py")

execl replaces the current process with the new one (even on Windows!) and you'll have only one process running at a time, so it should work. Note that execl's first two parameters should be the same - one for the python executable itself and one for the argv[0] it receives that should point to the executable.

Does that work?

Dj Gilcrease wrote:

···

Ya it works fine for me on Win32 as well, but Segfaults on *nix, even
the way you have it insted of in the OnExit code

On 2/10/07, Eli Golovinsky <gooli@tuzig.com> wrote:

Works fine on Windows XP SP2, Python 2.4.2, wxPython 2.8.1.1.

Did you try to put the code to run the second app after the call to the
first app's MainLoop? Conceptually you should never have two wx.App
objects alive at the same time, even during OnExit.

I mean something like this:

if __name__ == "__main__":
     app = BlankApp(0)
     app.MainLoop()
     del app

     import example1
     app = example1.BlankApp(0)
     app.MainLoop()

perfectly thanks

···

On 2/10/07, Eli Golovinsky <gooli@tuzig.com> wrote:

if __name__ == "__main__":
     app = BlankApp(0)
     app.MainLoop()

     import os
     import sys
     os.execl(sys.executable, sys.executable, "example1.py")
Does that work?