title: Exception handling in Tkinter
body: <p>So, I wrote a small Tkinter program in python. The program executes good, but its easy for an exception to occur if theres a non-digit character entered into a field.</p>
  
  <p>so, I tried to remedy it, but my remedy fails:</p>
  
  <p>and here is the issue:</p>
  
  <pre><code>try:
              self.laborOne = float(self.trimmerOne_Entry.get()) * 8
              self.laborTwo = float(self.trimmerTwo_Entry.get()) * 8
              self.laborThree = float(self.operator_Entry.get()) * 8
              self.addedThem = self.laborOne + self.laborTwo + self.laborThree
              self.laborTotal.set(str(self.addedThem))
              self.perUnitLabor = self.addedThem / 125
              self.laborUnit.set(str(self.perUnitLabor))
  except ValueError:
          tkinter.messagebox.showinfo('Error:', 'One or more of your values was not numeric. Please fix them.')
          self.performIt()
              self.performIt()
  </code></pre>
  
  <p>At first I tried just showing the messagebox in the error handling, but that closes the program when you click ok. SO, I tried recursion, calling the function to itself. When this happens, the dialog box just stays there. because self.performIt doesn't need an arg passed in, I passed (self) into it just to try it. THIS allows me to fix my values in the boxes, which is what I am looking for, but causes a different exception</p>
  
  <p>Anyway, how can I handle the ValueError exception without the program terminating, so that a user can enter corrected data?</p>
  
  <p>Complete code</p>
  
  <pre><code>import tkinter
  import tkinter.messagebox
  
  class MyGui:
      def __init__(self):
          #create the main window widget
          self.main_window = tkinter.Tk()
  
          #create 6 frames: 
          #one for each trimmers/operators pay,
          #one for buttons
          #one for outputs
          self.trimmerOne = tkinter.Frame(self.main_window)
          self.trimmerTwo = tkinter.Frame(self.main_window)
          self.operator = tkinter.Frame(self.main_window)
          self.rotaryLabor = tkinter.Frame(self.main_window)
          self.rotaryLaborUnit = tkinter.Frame(self.main_window)
          self.buttonFrame = tkinter.Frame(self.main_window)
  
          #create and pack widgets for Trimmer 1
          self.trimmerOne_Label = tkinter.Label(self.trimmerOne, text='Enter the payrate for trimmer 1: ')
          self.trimmerOne_Entry = tkinter.Entry(self.trimmerOne, width=10)
          self.trimmerOne_Label.pack(side='left')
          self.trimmerOne_Entry.pack(side='left')
  
          #create and pack widgets for Trimmer 2
          self.trimmerTwo_Label = tkinter.Label(self.trimmerTwo, text='Enter the payrate for trimmer 2: ')
          self.trimmerTwo_Entry = tkinter.Entry(self.trimmerTwo, width=10)
          self.trimmerTwo_Label.pack(side='left')
          self.trimmerTwo_Entry.pack(side='left')
  
          #create and pack widgets for Operator
          self.operator_Label = tkinter.Label(self.operator, text='Enter the payrate for operator: ')
          self.operator_Entry = tkinter.Entry(self.operator, width=10)
          self.operator_Label.pack(side='left')
          self.operator_Entry.pack(side='left')
  
          #create and pack widgets for rotaryLabor
          self.rotaryLabor_Label = tkinter.Label(self.rotaryLabor, text="This is what it cost's in trimmer labor: ")
          self.laborTotal = tkinter.StringVar() #to update with laborTotal_Label
          self.laborTotal_Label = tkinter.Label(self.rotaryLabor, textvariable=self.laborTotal)
          self.rotaryLabor_Label.pack(side='left')
          self.laborTotal_Label.pack(side='left')
  
          #create and pack widgets for labor Unit
          self.rotaryLaborUnit_Label = tkinter.Label(self.rotaryLaborUnit, text="This is the cost per part in trim labor: ")
          self.laborUnit = tkinter.StringVar() #to update with laborTotal_Label
          self.laborUnit_Label = tkinter.Label(self.rotaryLaborUnit, textvariable=self.laborUnit)
          self.rotaryLaborUnit_Label.pack(side='left')
          self.laborUnit_Label.pack(side='left')
  
          #create and pack the button widgets
          self.calcButton = tkinter.Button(self.buttonFrame, text = "Calculate", command=self.performIt)
          self.saveButton = tkinter.Button(self.buttonFrame, text = "Save", command=self.saveIt)
          self.quitButton = tkinter.Button(self.buttonFrame, text = "Quit", command=self.main_window.destroy)
          self.calcButton.pack(side="left")
          self.saveButton.pack(side="left")
          self.quitButton.pack(side="left")
  
          #pack the frames
          self.trimmerOne.pack()
          self.trimmerTwo.pack()
          self.operator.pack()
          self.rotaryLabor.pack()
          self.rotaryLaborUnit.pack()
          self.buttonFrame.pack()
  
          tkinter.mainloop()
  
      #define the function that will do the work:
      def performIt(self):
          try:
              self.laborOne = float(self.trimmerOne_Entry.get()) * 8
              self.laborTwo = float(self.trimmerTwo_Entry.get()) * 8
              self.laborThree = float(self.operator_Entry.get()) * 8
              self.addedThem = self.laborOne + self.laborTwo + self.laborThree
              self.laborTotal.set(str(self.addedThem))
              self.perUnitLabor = self.addedThem / 125
              self.laborUnit.set(str(self.perUnitLabor))
          except ValueError:
          tkinter.messagebox.showinfo('Error:', 'One or more of your values was not numeric. Please fix them.')
          self.performIt()
              self.performIt()
  
      def saveIt(self):
          self.laborOne = float(self.trimmerOne_Entry.get()) * 8
          self.laborTwo = float(self.trimmerTwo_Entry.get()) * 8
          self.laborThree = float(self.operator_Entry.get()) * 8
          self.addedThem = self.laborOne + self.laborTwo + self.laborThree
          self.laborTotal.set(str(self.addedThem))
          self.perUnitLabor = self.addedThem / 125
          self.laborUnit.set(str(self.perUnitLabor))
          file = open("log.txt", 'w')
          file.write("Trimmer One gets paid: " + str(self.laborOne))
          file.write("\n___________________________________________\n")
          file.write("Trimmer Two gets paid: " + str(self.laborTwo))
          file.write("\n___________________________________________\n")
          file.write("Operator gets paid: " + str(self.laborThree))
          file.write("\n___________________________________________\n")
          file.write("The sum of thier daily labor is: " + str(self.addedThem))
          file.write("\n___________________________________________\n")
          file.write("If production is reached, the labor cost is" + str(self.laborOne) + "per unit")
          file.write("\n___________________________________________\n")
          file.close()
  
  
  
  testRun = MyGui()
  </code></pre>