简体   繁体   中英

Exception handling in Tkinter

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.

so, I tried to remedy it, but my remedy fails:

and here is the issue:

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()

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

Anyway, how can I handle the ValueError exception without the program terminating, so that a user can enter corrected data?

Complete 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()

That's not how you catch errors. Do it like this:

except ValueError:
            tkinter.messagebox.showinfo('Error:', 'One or more of your values was not numeric. Please fix them.')

You don't need to call the function again.

In the ValueError exception handler, only an error needs to be shown. After performIt returns, the GUI will still be there.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM