I am building an application in Tkinter using several text widgets, and I am working on undo / redo functions that fire on a KeyPress event. (I do not use the text widget built into the stack, because I have objects without tkinter that can also be undone / redo, and I want to save everything on the same stack)
Before I started, I read the tutorials and documentation (e.g. http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm ) that gave me the impression event.char will be empty or None if the key pressed was " special ", not an alphanumeric / punctuation key.
This is actually not the case. Pressing Backspace on my keyboard (I use a Macbook Air running El Capitan) returns event.char from \ x7f.
By reading more about Tcl / TK, I also found out that the X keysyms list is platform-to-platform incompatible, and this, for example, on my Mac, the Shift keys seem to have keyym code 0. This means that my application interprets non-print characters like Delete, or the Shift key as print characters that messed around with my implementation.
I will handle KeyPress general events without a fingerprint separately, but I am still worried about the unexpected behavior of keyboard events for two reasons: 1) my program is designed for multi-platform and 2) there is a high probability that this program will be used by people using non-American keyboards.
My current solution using this as a reference is to check event.keysym_num to see if it is in the range of key numbers / key codes used by printed characters.
Here is a sample code:
from tkinter import * from tkinter import ttk root = Tk() textbox = Text(root, width=60, height=3) textbox.grid(sticky=(N, S, E, W)) def KeyboardEvent(event): if event.keysym_num > 0 and event.keysym_num < 60000: print('This is a printable key. The character is: %r keysym: %r' % \ (event.char, event.keysym_num)) else: print('This key is unprintable. The character is: %r keysym: %r' % \ (event.char, event.keysym_num)) textbox.bind('<KeyPress>', KeyboardEvent) root.mainloop()
My questions:
- Will my current method work, or are there any non-printable keys that will fail anyway?
- Is there a better way to talk about non-printable key events besides key print events in Tkinter / Python? (I considered using unicodecategory or curses.ascii.isprint (), but this check happens every time the user presses a key so that they seem redundant)
- Are there any other bugs with KeyPress events, especially the inconsistent behavior between Windows / Mac / Linux that I should be aware of? (note: I already know the problems with whitespace, such as tabs and carriage returns)
I am using Python 3 (installed with Homebrew) on a Mac. Thanks!