I have a wx python application that performs a series of steps for a particular input when you click on a button. The application works the first time, but then it throws an error if I try to click on the button a second time with a different input value.
I have two questions: 1.) How do I fix my code below so that it stops throwing this error message?
2.) What specific code should I add so that any error message such as this one is shown to the end user in a dialog box? I would like it to be able to gracefully kill the whole process that threw the error (starting with the button click) and replace the progress bar with a new dialog box that gives the error message and allows the user to click a button that will take them back to the application's main window so that they can try to click the button again to make it work with new input. I am about to wrap this up in an exe file soon, but right now the only error handling I have is the error message in the python shell. Since users will not have the python shell, I need the error messages to come up in the manner described in this paragraph. Notice that my OnClick() function here instantiates a class. I make use of a number of different classes in my actual code, each of which is very complex, and I need the functionality I am asking for here to be able to handle errors that happen deep in the bowels of the various classes that are being instantiated by the OnClick() function.
Here is a very simplified but working version of my code:
import wxversion
import wx
ID_EXIT = 130
class MainWindow(wx.Frame):
def __init__(self, parent,id,title):
wx.Frame.__init__(self,parent,wx.ID_ANY,title, size = (500,500), style = wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE)
# A button
self.button =wx.Button(self, label="Click Here", pos=(160, 120))
self.Bind(wx.EVT_BUTTON,self.OnClick,self.button)
# the combobox Control
self.sampleList = ['first','second','third']
self.lblhear = wx.StaticText(self, label="Choose TestID to filter:", pos=(20, 75))
self.edithear = wx.ComboBox(self, pos=(160, 75), size=(95, -1), choices=self.sampleList, style=wx.CB_DROPDOWN)
# the progress bar
self.progressMax = 3
self.count = 0
self.newStep='step '+str(self.count)
self.dialog = None
#-------Setting up the menu.
# create a new instance of the wx.Menu() object
filemenu = wx.Menu()
# enables user to exit the program gracefully
filemenu.Append(ID_EXIT, "E&xit", "Terminate the program")
#------- Creating the menu.
# create a new instance of the wx.MenuBar() object
menubar = wx.MenuBar()
# add our filemenu as the first thing on this menu bar
menubar.Append(filemenu,"&File")
# set the menubar we just created as the MenuBar for this frame
self.SetMenuBar(menubar)
#----- Setting menu event handler
wx.EVT_MENU(self,ID_EXIT,self.OnExit)
self.Show(True)
def OnExit(self,event):
self.Close(True)
def OnClick(self,event):
#SECOND EDIT: added try: statement to the next line:
try:
if not self.dialog:
self.dialog = wx.ProgressDialog("Progress in processing your data.", self.newStep,
self.progressMax,
style=wx.PD_CAN_ABORT
| wx.PD_APP_MODAL
| wx.PD_SMOOTH)
self.count += 1
self.newStep='Start'
(keepGoing, skip) = self.dialog.Update(self.count,self.newStep)
TestID = self.edithear.GetValue()
self.count += 1
self.newStep='Continue.'
(keepGoing, skip) = self.dialog.Update(self.count,self.newStep)
myObject=myClass(TestID)
print myObject.description
self.count += 1
self.newStep='Finished.'
(keepGoing, skip) = self.dialog.Update(self.count,self.newStep)
**#FIRST EDIT: Added self.count = 0 on the foll开发者_开发百科owing line**
self.count = 0
self.dialog.Destroy()
#SECOND EDIT: Added the next seven lines to handle exceptions.
except:
self.dialog.Destroy()
import sys, traceback
xc = traceback.format_exception(*sys.exc_info())
d = wx.MessageDialog( self, ''.join(xc),"Error",wx.OK)
d.ShowModal() # Show it
d.Destroy() #finally destroy it when finished
class myClass():
def __init__(self,TestID):
self.description = 'The variable name is: '+str(TestID)+'. '
app = wx.PySimpleApp()
frame = MainWindow(None,-1,"My GUI")
app.MainLoop()
My actual code is A LOT more complex, but I created this dummy version of it to illustrate the problems with it. This code above works when I run it in python the first time I click the button. But if I try to click the button a second time, I get the following error message in the python shell:
Traceback (most recent call last):
File "mypath/GUIdiagnostics.py", line 55, in OnClick
(keepGoing, skip) = self.dialog.Update(self.count,self.newStep)
File "C:\Python26\lib\site-packages\wx-2.8-msw-unicode\wx\_windows.py", line 2971, in Update
return _windows_.ProgressDialog_Update(*args, **kwargs)
wx._core.PyAssertionError: C++ assertion "value <= m_maximum" failed at ..\..\src\generic\progdlgg.cpp(337) in wxProgressDialog::Update(): invalid progress value
FIRST EDIT: OK, I answered my first question above by adding
self.count = 0
above
self.dialog.Destroy()
in the code above. But what about my second question regarding error handling in the code above? Can anyone help me with that? Surely, error handling in wxpython is a common issue for which there are known methods. I am going to use py2exe to wrap this application up into an exe file.
SECOND EDIT: I answered my second question above with the try: , except: statement that I have added to my code above. Funny, this is the first time that no one on stack overflow has been able to answer my question. I am new to this type of programming, so a lot of things I am just picking up as they come. This question is now answered.
精彩评论