[wxPython] Only 1 wxApp per process - revisited

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

[wxPython] Only 1 wxApp per process - revisited

Ken Seehof-2
If your app raises an exception during initialization, you will
be unable to restart your app because of the infamous
"Only 1 wxApp per process" problem.

Here's Robins solution plus a traceback that has solved this
problem for me:

class MyFrame(BaseFrame):
  def __init__(self):
    BaseFrame.__init__(self, None, -1,
        "Hello", wxDefaultPosition, wxSize(600,400))
   try:
     # ... All your initialization code ...
   except:
     self.Destroy() # causes main loop to exit
     traceback.print_exc() # and you still get your trace

This belongs in the demo code, and in all tutorials and relevant
documentation because -everyone- who is getting started with
wxPython (or maybe just the ones that write bugs) will soon
encounter this problem, and it will cost them a lot of time because
it disrupts the edit-run-debug cycle.

- Ken Seehof
 

Reply | Threaded
Open this post in threaded view
|

Re: [wxPython] Only 1 wxApp per process - revisited

Gerrit Holl-3
Ken Seehof wrote on 950965941:

> If your app raises an exception during initialization, you will
> be unable to restart your app because of the infamous
> "Only 1 wxApp per process" problem.
>
> Here's Robins solution plus a traceback that has solved this
> problem for me:
>
> class MyFrame(BaseFrame):
>   def __init__(self):
>     BaseFrame.__init__(self, None, -1,
>         "Hello", wxDefaultPosition, wxSize(600,400))
>    try:
>      # ... All your initialization code ...
>    except:
>      self.Destroy() # causes main loop to exit
>      traceback.print_exc() # and you still get your trace

Can't you just use __del__ for this? It's called when an exception
is raised - and if the interpreter dumps core, exceptsions are
also not handled.

BTW, please comment by comparsion to all Python GUI's:
http://www.nl.linux.org/~gerrit/gui.html

regards,
Gerrit.

--
Comparison Python GUI's: http://www.nl.linux.org/~gerrit/gui.html


_______________________________________________
wxPython-users maillist  -  [hidden email]
http://starship.python.net/mailman/listinfo/wxpython-users



Reply | Threaded
Open this post in threaded view
|

Re: [wxPython] Only 1 wxApp per process - revisited

Robin Dunn
In reply to this post by Ken Seehof-2

This belongs in the demo code, and in all tutorials and relevant
documentation because -everyone- who is getting started with
wxPython (or maybe just the ones that write bugs) will soon
encounter this problem, and it will cost them a lot of time because
it disrupts the edit-run-debug cycle.

 
Thanks Ken, I'll do that.
 
--
Robin Dunn
Software Craftsman
[hidden email]
http://AllDunn.com/robin/
http://AllDunn.com/wxPython/  Check it out!
Reply | Threaded
Open this post in threaded view
|

Re: [wxPython] Only 1 wxApp per process - revisited

Robin Dunn
In reply to this post by Gerrit Holl-3
> Ken Seehof wrote on 950965941:
> > If your app raises an exception during initialization, you will
> > be unable to restart your app because of the infamous
> > "Only 1 wxApp per process" problem.
> >
> > Here's Robins solution plus a traceback that has solved this
> > problem for me:
> >
> > class MyFrame(BaseFrame):
> >   def __init__(self):
> >     BaseFrame.__init__(self, None, -1,
> >         "Hello", wxDefaultPosition, wxSize(600,400))
> >    try:
> >      # ... All your initialization code ...
> >    except:
> >      self.Destroy() # causes main loop to exit
> >      traceback.print_exc() # and you still get your trace
>
> Can't you just use __del__ for this? It's called when an exception
> is raised - and if the interpreter dumps core, exceptsions are
> also not handled.
>

Because we're not worried so much about the destruction of the Python object
as we are the C++ object.   Besides __del__ won't be called unless all
references to the Python object are gone.  If any EVT_* functions were called
binding events to methods of the object before the exception happened then
there are internal references that won't be cleared until the C++ object is
deleted.  Calling self.Destroy() does that for you.

Once that partially created frame has been destroyed, then the MainLoop will
exit and the app object will cleanup after itself.

--
Robin Dunn
Software Craftsman
[hidden email]
http://AllDunn.com/robin/
http://AllDunn.com/wxPython/  Check it out!



_______________________________________________
wxPython-users maillist  -  [hidden email]
http://starship.python.net/mailman/listinfo/wxpython-users



Reply | Threaded
Open this post in threaded view
|

[wxPython] OT: Advanced Python Question

Cliff Baeseman
Hi All,

I have a problem with some code I am working for a app but it is mainly a
advanced python question.

If I can explain this correctly.

I have a module that I load at runtime and I grab a function handle by calling
getattr(). I have a function that is actually loading and calling the get attr
method and a string is being passed in that looks like this (1,'mystring',2)
now the method grabbed using getattr() is expecting multiple arguments. So the
basic form of the question is how can  I call the method passing the arguments.
BTW I never know in advance how many arguments I will have, it is just supposed
to call the method sending the arguments.

I do not know if I explained this correctly or not but here is a little of the
code

def CallMethod(reqmethod,params):
  clsobj = dbtest()

  if params ==():
   mthd = getattr(clsobj,reqmethod)
   rtn = mthd()
  else:
   print params
   mthd = getattr(clsobj,reqmethod)
   rtn = mthd(params)   <--need to call this correctly sending in the params
  return rtn

Thanx for any insight to this.

Cliff

_______________________________________________
wxPython-users maillist  -  [hidden email]
http://starship.python.net/mailman/listinfo/wxpython-users



Reply | Threaded
Open this post in threaded view
|

Re: [wxPython] OT: Advanced Python Question

Ben Darnell
On Sun, Feb 20, 2000 at 04:44:12AM -0600, Cliff Baeseman wrote:
> I have a module that I load at runtime and I grab a function handle
> by calling getattr(). I have a function that is actually loading and
> calling the get attr method and a string is being passed in that looks
> like this (1,'mystring',2) now the method grabbed using getattr() is
> expecting multiple arguments. So the basic form of the question is
> how can I call the method passing the arguments.  BTW I never know in
> advance how many arguments I will have, it is just supposed to call
> the method sending the arguments.

I think the builtin function apply() is what you're looking for.

-Ben

--
Ben Darnell              [hidden email]
http://thoughtstream.org


_______________________________________________
wxPython-users maillist  -  [hidden email]
http://starship.python.net/mailman/listinfo/wxpython-users



Reply | Threaded
Open this post in threaded view
|

Re: [wxPython] OT: Advanced Python Question

Cliff Baeseman
In reply to this post by Cliff Baeseman
Please disregard the function apply does exactly this.

Cliff

On Sun, 20 Feb 2000, you wrote:

> Hi All,
>
> I have a problem with some code I am working for a app but it is mainly a
> advanced python question.
>
> If I can explain this correctly.
>
> I have a module that I load at runtime and I grab a function handle by calling
> getattr(). I have a function that is actually loading and calling the get attr
> method and a string is being passed in that looks like this (1,'mystring',2)
> now the method grabbed using getattr() is expecting multiple arguments. So the
> basic form of the question is how can  I call the method passing the arguments.
> BTW I never know in advance how many arguments I will have, it is just supposed
> to call the method sending the arguments.
>
> I do not know if I explained this correctly or not but here is a little of the
> code
>
> def CallMethod(reqmethod,params):
>   clsobj = dbtest()
>
>   if params ==():
>    mthd = getattr(clsobj,reqmethod)
>    rtn = mthd()
>   else:
>    print params
>    mthd = getattr(clsobj,reqmethod)
>    rtn = mthd(params)   <--need to call this correctly sending in the params
>   return rtn
>
> Thanx for any insight to this.
>
> Cliff
>
> _______________________________________________
> wxPython-users maillist  -  [hidden email]
> http://starship.python.net/mailman/listinfo/wxpython-users

_______________________________________________
wxPython-users maillist  -  [hidden email]
http://starship.python.net/mailman/listinfo/wxpython-users



Reply | Threaded
Open this post in threaded view
|

Re: [wxPython] Only 1 wxApp per process - revisited

Ken Seehof-2
In reply to this post by Ken Seehof-2
Yeah, I just ran into that too.  So I guess you have to apply the same logic again to OnPaint:

    def OnPaint (self, e):
        try:
            pdc = wxPaintDC(self)
            # . . .
        except:
            self.Destroy()
            traceback.print_exc()

Well, not really the same logic, but the same code :-)

I was thinking the problem seems to be that the OnPaint handler never returns, so the update region never gets reset or something like that, but it seems to be more complicated than that since if I omit the self.Destroy() and simply let the function return, I get the same vanity effect.

Anyway this seems to work pretty well since you can't send a message to a window once it's been destroyed.  I certainly won't promise that this is portable :-)  If anyone does try this on something other than Windows, let me know.

If you want something more robust, don't write buggy code in the first place :-)

- Ken

Tom Fenn wrote:

  This doesn't seem to work very well for me, though it does get rid of the "only 1 ..." error, it introduces new problems.  Example code below.  Running under Pythonwin it works fine the first time through, but the second time I run the program, all hell breaks lose.  In my code, I've intentionally introduced an error in the OnPaint routine for the wxFrame.  For some reason, the Frame wants to paint itself before closing.  This leads to a perpetual string of tracebacks printed to stdout.  Somebody should tell wxWindows that vanity is a sin. Tom Fenn 

from wxPython.wx import *
import traceback class MyFrame(wxFrame):
 def __init__(self):
  wxFrame.__init__(self,None,-1,"Hello World",(30,30),(200,100))
  try:
   dc = wxClientDC(self)
   self.DrawMe(dc)
  except:
   self.Destroy()
   traceback.print_exc()
  return
 def DrawMe(self,dc):
  dc.BeginDrawing()
  dc.SetBackground(wxRED_BRUS) #exception here
  dc.Clear()
  dc.SetBrush(wxGREEN_BRUSH)
  dc.SetPen(wxBLACK_PEN)
  dc.DrawCircle(100,50,20)
  dc.EndDrawing()
  return
 def OnPaint(self,event):
  dc = wxPaintDC(self)
  self.DrawMe(dc)
  return
 
class MyApp(wxApp):
 def OnInit(self):
  frame = MyFrame()
  frame.Show(true)
  self.SetTopWindow(frame)
  return true app = MyApp()
app.MainLoop()

----- Original Message -----
Sent: Saturday, February 19, 2000 4:12 PM
Subject: [wxPython] Only 1 wxApp per process - revisited
 If your app raises an exception during initialization, you will
be unable to restart your app because of the infamous
"Only 1 wxApp per process" problem.

Here's Robins solution plus a traceback that has solved this
problem for me:

class MyFrame(BaseFrame):
  def __init__(self):
    BaseFrame.__init__(self, None, -1,
        "Hello", wxDefaultPosition, wxSize(600,400))
   try:
     # ... All your initialization code ...
   except:
     self.Destroy() # causes main loop to exit
     traceback.print_exc() # and you still get your trace

This belongs in the demo code, and in all tutorials and relevant
documentation because -everyone- who is getting started with
wxPython (or maybe just the ones that write bugs) will soon
encounter this problem, and it will cost them a lot of time because
it disrupts the edit-run-debug cycle.

- Ken Seehof