lemonshark lemonshark - 1 year ago 88
Python Question

python isdigit() returning unexpected result

I'm making a basic BMI calculation program for a class assignment using TKinter for the GUI, and ran into a problem when trying to validate the user's input.
I'm trying to only allow numerical input and to deactivate the 'calculate' button and send an error message when the user enters anything that's not a number. However, at the minute it will throw up an error for a single digit number (e.g. 2) but will accept multiple digits (e.g. 23). I'm quite new to this so could you please explain why this is happening, or if there's a better way to write this?

Here are the relevant parts of my code:

#calculate button
cal = ttk.Button(main, text = 'Calculate!')
cal.grid(row = 4, column = 2)

#height entry box
hb = tk.Entry(main, textvariable = height)
hb.grid(row = 2, column = 2)
hb.bind('<Key>', lambda event: val(hb.get()))

#validation error message
vrs = tk.Label(main, text = 'Please enter a number in the box')
vrs.grid(row = 8, column = 2)
#so that its position is saved but won't appear until validation fails

#validation function
def val(value):
if value.isdigit():

Thanks in advance for your help.

Answer Source

The first thing you should do to debug this is to print out value inside of val, to see if your assumptions are correct. Validating your assumptions is always the first step in debugging.

What you'll find is that your function is being called before the digit typed by the user is actually inserted into the widget. This is expected behavior.

The simple solution is to put your binding on <KeyRelease>, since the default behavior of inserting the character is on <KeyPress>:

hb.bind('<Any-KeyRelease>', lambda event: val(hb.get()))

Even better would be to use the Entry widget's built-in validation features. For an example, see http://stackoverflow.com/a/4140988/7432