tkinter keypress events are a mess for numpad keys

Rick Johnson rantingrickjohnson at gmail.com
Sun Sep 3 07:31:11 EDT 2017


Irmen de Jong wrote:
> Using tkinter in python3, I was trying to intercept
> individual keypresses (and releases) of keys on the numeric
> keypad. I want to use this as a simple joystick simulation.
> While you can bind the <KeyPress> event, actually doing
> something sensible with it in a cross platform way seems
> utterly impossible.  

Personally, none of my applications have needed to
differentiate between the "number-keys-on-the-keypad" and
the "number-keys-on-the-main-keyboard", so i'm not sure if
there is a clean solution here, much less a clean cross-
platform solution...

And although my initial reaction to your inquiry (assuming
there is no clean solution here...) was to lay blame on
tkinter for not observing its own cross-platform mandate,
the more i think about this, the more i wonder if tkinter
_should_ differentiate between these duplicate number keys?

Hmm...

Considering that (at a very high level) the sole purpose of
a keyboard is to send character information to a machine by
mapping keypresses to characters -- and not so much
concerning itself with key locations or duplicate keys -- i
think what you are doing is expecting a keyboard to function
in a manner for which it was not intented to function, and
while i'm a big fan of multi-purpose tools, i understand
also the practical importance of simplistic, single-purpose
design.

What are your thoughts on this?

> The distinguishing attribute of the event object is
> different depending on what OS you're using (keysym,
> keycode, keysym_num) and on Windows registering some keys
> doesn't even seem to work (or they're confused with the
> same keys on the normal keyboard area). The keysym
> names/values in the documentation are not correct either

Barring a clean cross-platform solution, i would suggest
one of the following: 
    
    (1) Appeal to the Tcl/Tk folks to standardize these "event
    codes". After all, _they_ are the ones who market TK as a
    cross platform GUI.
        
or 

    (2) Create your own mapping that can translate the keycodes,
    keysyms, or keysym_nums to something consistent between the
    platforms.

I have a feeling that #2 will be more efficient.

The good new is, that if the number keys (0-9) are your only
concern, then we're only talking about ten keys over three
major platforms here -- so (10 x 3 = 30) mappings --
shouldn't be too difficult. Of course, with solution #2 your
code will be at the mercy of future changes that are beyond
your control (aka: brittle), however, i doubt these codes
would change very much over time, if at all. A simple
template might look something like this:

    
    evtMap = {...}
    
    w.bind("<KeyPress>", _evtKeyPress)
    
    def _evtTrans(event):
        ...
    
    def _evtKeyPress(event):
        _evtTrans(event)
        # Process event here...


Sucks to do this, but sometimes you have no choice.

PS: If i had nickle for every time i had to take a big
hammer and pound dents out of tkinter's hull to achieve a
more elegant work flow, well, you know the story. Tkinter
may be a rusty old tub, but she gets the job done if you're
willing to periodically scrape the barnacles from her belly,
patch the holes and apply a new coat of lead paint. As any
old salt will testify, she's a labour of love. 




More information about the Python-list mailing list