Home > other >  TTK Enty validation issue
TTK Enty validation issue

Time:11-22

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:

  1. I am not able to make it accept "," and ".";

  2. 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!

  • Related