Tkinter Ttk Python: limiting text entry widget values to numbers and limiting amount of characters
Question: Probably an easy one here: in tkinter, ttk, how do you limit the amount of
characters that can be input by the user into an entry field? For example,
only allowing the user to insert one character and limiting the ability to
insert any others?

Additionally, how would I then make it so that only an intiger can be input
into said text entry field, so that it doesn't allow the user to input any
characters that aren't {0:9}?

Thanks :) Btw i'm fairly new to programming so the simpler put, the better :)

If it's any help to showing what to do, here's my program so far:

    
    
    from tkinter import *
    from tkinter import ttk
    
    def calculate(*args):
        try:
            valuex=int(x.get())
            valuey=int(y.get())
            valuez=int(z.get())
            cappf.set(int(str(valuex)+str(valuey))*10**valuez)
            capnf.set(int(str(valuex)+str(valuey))*10**valuez*10**-3)
            capuf.set(int(str(valuex)+str(valuey))*10**valuez*10**-6)
        except ValueError:
            pass
    
    root=Tk()
    root.title('Capacitor Calculator')
    
    mainframe=ttk.Frame(root, padding='10 10 10 10')
    mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
    mainframe.columnconfigure(0, weight=1)
    mainframe.rowconfigure(0, weight=1)
    
    x=StringVar()
    x_entry=ttk.Entry(mainframe, width=3, textvariable=x)
    x_entry.grid(column=1, row=2, sticky=(W,E))
    y=StringVar()
    y_entry=ttk.Entry(mainframe, width=3, textvariable=y)
    y_entry.grid(column=1, row=3, sticky=(W,E))
    z=StringVar()
    z_entry=ttk.Entry(mainframe, width=3, textvariable=z)
    z_entry.grid(column=1, row=4, sticky=(W,E))
    
    cappf=StringVar()
    capnf=StringVar()
    capuf=StringVar()
    
    ttk.Button(mainframe, width=7, text='Calculate', command=calculate).grid(column=2, row=5, sticky=(N, E, S, W))
    ttk.Label(mainframe, textvariable=cappf).grid(column=2, row=2, sticky=N)
    ttk.Label(mainframe, textvariable=capnf).grid(column=2, row=3, sticky=N)
    ttk.Label(mainframe, textvariable=capuf).grid(column=2, row=4, sticky=N)
    ttk.Label(mainframe, text='Input:').grid(column=1, row=1, sticky=N)
    ttk.Label(mainframe, text='Amount:').grid(column=2, row=1, sticky=N)
    ttk.Label(mainframe, text='Units:').grid(column=3, row=1, sticky=N)
    ttk.Label(mainframe, text='pf').grid(column=3, row=2, sticky=N)
    ttk.Label(mainframe, text='nf').grid(column=3, row=3, sticky=N)
    ttk.Label(mainframe, text='uf').grid(column=3, row=4, sticky=N)
    ttk.Button(mainframe, width=7, text='Quit', style='red.TButton', command=root.destroy).grid(column=2, row=6, sticky=(N, E, S, W))
    ttk.Style().configure('red.TButton', foreground='red', padding=6, font='Corbel 18')
    ttk.Style().configure('TLabel', padding=6, font='Corbel 16', foreground='#0077AF')
    ttk.Style().configure("TButton", padding=6, relief="flat", font='Corbel 18', foreground='#00AA11')
    
    for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=3)
    x_entry.focus()
    y_entry.focus()
    z_entry.focus()
    
    root.bind('<Return>', calculate)
    root.mainloop()
    


Answer: The entry widget supports a validation callback, specified by setting the
validation mode (via the `validate` property) and providing the callback
itself (via the `validatecommand` property). The Tkinter documentation for how
to use it is very poor, unfortunately.

The validation mode can be the strings `focusOut` (to apply the validation
when the focus leaves the widget) and `key` (to apply it when the user presses
a key). And `focus` and `focusIn` but I've not found them to be so useful.

The validation callback should return a boolean that states whether the
current (== new, in the case of `key` validation) contents are valid. If the
validation fails, the change is rejected (the contents are reset) and the
invalid contents callback is invoked (via the `invalidcommand` property) which
can do things like sound the bell or make the screen flash.

* * *

A more elaborate validation mechanism is to always _officially_ claim that the
edit is valid, but to change the background of the entry (or use some other
indicator) to show that the edit _will be rejected_. Then, only do full
validation/rejection on overall submission of the form (you were going to do
that anyway, yes?). Like that, temporarily invalid states are permitted so
long as the user goes back and fixes them before finishing their session. This
is quite a lot more usable.

