views:

851

answers:

6

I'm trying wxpython for the first time. I've wrote a GUI for a python program and when I run it, it produces some error in the GUI, but the GUI disappears very quickly, quickly enough for me to be unable to read the error info.

Is there any log that I can check for the error message? (I'm running Mac OS X) or any other way?

Thanks in advance for any help.

Update: Here's the code that's giving me the problem...

#!/usr/bin/python

import wx

class MyApp (wx.Frame):
    def __init__(self, parent, id, title):
     wx.Frame.__init__(self, parent, id, title, size=(390, 350))
 menubar = wx.MenuBar()
 help = wx.Menu()
 help.Append(ID_ABOUT, '&About')
 self.Bind(wx.EVT_MENU, self.OnAboutBox, id=wx.ID_ABOUT)
 menubar.Append(help, '&Help')
 self.SetMenuBar(menubar)

 self.Centre()
 self.Show(True)

 panel = wx.Panel(self, -1)

 font = wx.SystemSettings_GetFont(wx.SYS_SYSTEM_FONT)
 font.SetPointSize(9)

 vbox = wx.BoxSizer(wx.VERTICAL)

 hbox1 = wx.BoxSizer(wx.HORIZONTAL)
 st1 = wx.StaticText(panel, -1, 'Class Name')
 st1.SetFont(font)
 hbox1.Add(st1, 0, wx.RIGHT, 8)
 tc = wx.TextCtrl(panel, -1)
 hbox1.Add(tc, 1)
 vbox.Add(hbox1, 0, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, 10)

 vbox.Add((-1, 10))

 hbox2 = wx.BoxSizer(wx.HORIZONTAL)
 st2 = wx.StaticText(panel, -1, 'Matching Classes')
 st2.SetFont(font)
 hbox2.Add(st2, 0)
 vbox.Add(hbox2, 0, wx.LEFT | wx.TOP, 10)

 vbox.Add((-1, 10))

 hbox3 = wx.BoxSizer(wx.HORIZONTAL)
 tc2 = wx.TextCtrl(panel, -1, style=wx.TE_MULTILINE)
 hbox3.Add(tc2, 1, wx.EXPAND)
 vbox.Add(hbox3, 1, wx.LEFT | wx.RIGHT | wx.EXPAND, 10)

 vbox.Add((-1, 25))

 hbox4 = wx.BoxSizer(wx.HORIZONTAL)
 cb1 = wx.CheckBox(panel, -1, 'Case Sensitive')
 cb1.SetFont(font)
 hbox4.Add(cb1)
 cb2 = wx.CheckBox(panel, -1, 'Nested Classes')
 cb2.SetFont(font)
 hbox4.Add(cb2, 0, wx.LEFT, 10)
 cb3 = wx.CheckBox(panel, -1, 'Non-Project classes')
 cb3.SetFont(font)
 hbox4.Add(cb3, 0, wx.LEFT, 10)
 vbox.Add(hbox4, 0, wx.LEFT, 10)

 vbox.Add((-1, 25))

 hbox5 = wx.BoxSizer(wx.HORIZONTAL)
 btn1 = wx.Button(panel, -1, 'Ok', size=(70, 30))
 hbox5.Add(btn1, 0)
 btn2 = wx.Button(panel, -1, 'Close', size=(70, 30))
 hbox5.Add(btn2, 0, wx.LEFT | wx.BOTTOM , 5)
 vbox.Add(hbox5, 0, wx.ALIGN_RIGHT | wx.RIGHT, 10)

 panel.SetSizer(vbox)
 self.Centre()
 self.Show(True)

 def OnAboutBox(self, event):
  description = """ describe my app here """

  licence = """ blablabla """


  info = wx.AboutDialogInfo()

  info.SetIcon(wx.Icon('icons/icon.png', wx.BITMAP_TYPE_PNG))
  info.SetName('')
  info.SetVersion('1.0')
  info.SetDescription(description)
  info.SetCopyright('')
  info.SetWebSite('')
  info.SetLicence(licence)
  info.AddDeveloper('')
  info.AddDocWriter('')
  info.AddArtist('')
  info.AddTranslator('')

  wx.AboutBox(info) 

app = wx.App()
MyApp (None, -1, 'Go To Class')
app.MainLoop()
A: 

Start the application from the command line (I believe its called 'Terminal' in OS X) as noted below instead of double clicking on the python file. This way when the application crashes you'll see the stack trace.

python NameOfScript.py

Alternatively, you can redirect output to a log file:

f=open('app.log','w')
import sys
sys.stdout=f
sys.stderr=f
Mark Roddy
well, actually I do start it from the terminal and still nothing is outputted :\ I'll try the redirection tip.
rogeriopvl
I tried the redirection and the log file ends up empty :\
rogeriopvl
A: 

Add print statements to your program, so you can tell how it's starting up and where it ends up dying (by running from the terminal as you already said you do).

Alex Martelli
A: 

You could also run your project from a Python IDE, such as Eric IDE. You get the added bonus of being able to trace, watch variables and tons of other cool stuff! :-)

Joce
+1  A: 

Here's a way to have the error be reported in the GUI instead of the console, via a MessageDialog. You can use the show_error() method anywhere an exception is caught, here I just have it being caught at the top-most level. You can change it so that the app continues running after the error occurs, if the error can be handled.

import wx
import sys
import traceback

def show_error():
    message = ''.join(traceback.format_exception(*sys.exc_info()))
    dialog = wx.MessageDialog(None, message, 'Error!', wx.OK|wx.ICON_ERROR)
    dialog.ShowModal()

class Frame(wx.Frame):
    def __init__(self):
        super(Frame, self).__init__(None, -1, 'My Frame')
    def cause_error(self):
        raise Exception, 'This is a test.'

def main():
    app = wx.PySimpleApp()
    try:
        frame = Frame()
        frame.Show()
        frame.cause_error()
        app.MainLoop()
    except:
        show_error()

if __name__ == '__main__':
    main()
FogleBird
+2  A: 

Launch from a Python IDE with a debugger.

Running in WingIDE immediatelly pinpoints the two problems:

  • ID_ABOUT should be wx.ID_ABOUT (line #4 of __init__).
  • OnAboutBox (the entire method) is indented one step too much. As written, it's a local function inside __init__. Move the whole method one step to the left to make it a method of MyApp.
Jon-Eric
+2  A: 

not sure about the mac version, but wxPython has a built in way to redirect errors to a window (which will unfortunately close when your application crashes, but it's useful for catching errors that silently fail) or to a log file (only updated after your application closes):

app = wx.App(redirect=True) 
app = wx.App(redirect=True,filename=mylog.txt)

these will work regardless of how you start your application. See here for more

Albert Visser