Search code examples
pythontkintertk-toolkitkey-bindings

How to bind ONLY ASCII keys in tkinter?


I want to bind only ASCII keys using tkinter. I know how to bind it selectively (per key) or even by binding it to all keyboard keys (by using <Key> or <KeyPress>), but problem is, I don't know how to do the same for every ASCII keys.

Here is what I tried so far:

  1. Using <Key> or <KeyPress> binding for catching all keyboard keys (doesn't support mouse keys):
import tkinter as tk

def key_press(event):
    label.config(text = f'char Pressed: {event.char!r}')
    label2.config(text=f'keysym Pressed: {event.keysym!r}')

root = tk.Tk()
label = tk.Label(root, text='Press a key')
label2 = tk.Label(root, text='Press a key')
label.pack()
label2.pack()
root.bind('<Key>', key_press)
root.mainloop()
  1. Using per key binding (need to know the name/keysym first, as seen on the tkinter documentation):
import tkinter as tk

def key_press(event):
    label.config(text = f'char Pressed: {event.char!r}')
    label2.config(text=f'keysym Pressed: {event.keysym!r}')

root = tk.Tk()
label = tk.Label(root, text='Press a key')
label2 = tk.Label(root, text='Press a key')
label.pack()
label2.pack()
# here we only use the K and BackSpace key as example
root.bind('<BackSpace>', key_press)
root.bind('<K>', key_press)
root.mainloop()

How can I bind a function only to all ascii keys using just tkinter? (no third-party module if possible)


Solution

  • The easiest and efficient solution to bind only ascii chars in my opinion is to use event.char. event.char corresponds to %A and will be an empty string if no printable character is parsed. To access the individual character you can use repr as it is implemented in tkinter

    I did not used event.keycode because for Multi_key they seem unreliable. Also included del-key but found no better way as to use keysym for it, feel free to find a better way

    Example code:

    import tkinter as tk
    
    def isascii(event):
        if event.char != '':
            char = list(event.char)[0] #'^' or '`' is only parsed as doubles in Windows
            if ord(char) <= 127: #avoid non-ascii like '²' or '³' or '´'
                print(
                    repr(char), #printable character
                    ord(char) #corresponding ascii value
                    )
        elif event.keysym == 'Delete':
            print('backspace / delete', 127)
    
    root = tk.Tk()
    root.bind('<Key>', isascii)
    root.mainloop()
    

    compressed version:

    import tkinter as tk
    
    def isascii(event):
        if event.char != '' and ord((char := list(event.char)[0])) <= 127:
            print(
                repr(char), #printable character
                ord(char) #corresponding ascii value
                )
        elif event.keysym == 'Delete': print('delete', 127)
    
    root = tk.Tk()
    root.bind('<Key>', isascii)
    root.mainloop()