I am writing my very first GUI app with Py and Tkinter (Ttkinter). I want to be sure that the user can write only digits, "," and "." in the entries field. So far I did this but I have a couple of issues:
I am not able to make it accept "," and ".";
Using this method I can't use the clean functions that I wrote to clean the entries widget.
#Validation function
def dig_check(input):
if input.isdigit():
print(input)
return True
else:
print(input)
return False
#Clean function
def clean_calc():
r_top_entry.delete(0,END)
r_bot_entry.delete(0,END)
p_thick_entry.delete(0,END)
b_angle_deg_entry.delete(0,END)
b_angle_m_entry.delete(0,END)
b_angle_s_entry.delete(0,END)
b_height_entry.delete(0,END)
De_label.config(text="-")
Dm_label.config(text="-")
Di_label.config(text="-")
de_label.config(text="-")
dm_label.config(text="-")
di_label.config(text="-")
deg_value.config(text="-")
min_value.config(text="-")
sec_value.config(text="-")
#Entry widget example
r_top_entry = ttk.Entry(blank_frame, width=10, validate="key", validatecommand=(root.register(dig_check),"%P"))
Can someone help me and explain me what am I doing wrong?
CodePudding user response:
You'll need to modify your validator to accept the other characters
def dig_check(usr_input):
# accept digits, '.', ',', or empty values
char = usr_input[-1] # get the latest character added to the Entry
if char.isdigit() or char in '.,' or char == '':
return True
return False
It's good to accept empty values as well so the user can delete the contents of the Entry
. You'll need to check for these after the fact, but if you don't catch them here your Entry
will always have to have some value, which is probably not what you want.
Note that this will also permit multiple consecutive '.' and ',' characters, and won't dictate where those characters are allowed. For something more stringent, you'll probably want to look at RegEx.
Also, I've changed input
to usr_input
since input
is a reserved word (it's a function)
If you want to be more prescribed in your validation (and generally, you should!), you can do something like this:
import re
def dig_check(usr_input):
pattern = re.compile(r'^\d (?:,?\d*)*.?\d*$|^$')
if re.search(pattern, user_input):
return True
return False
Bear in mind that the RegEx pattern here isn't exhaustive, and can allow for things like multiple consecutive commas...I'm just demonstrating a point!