classification
Title: turtle.onkey doesn't pass key information when key is None
Type: enhancement Stage: test needed
Components: Library (Lib) Versions: Python 3.8
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: gregorlingl, je1234, willingc
Priority: normal Keywords:

Created on 2018-04-22 18:34 by je1234, last changed 2018-04-27 18:28 by terry.reedy.

Messages (1)
msg315627 - (view) Author: J E (je1234) Date: 2018-04-22 18:34
I use the turtle module to teach Python to university students. The turtle.onkey function allows a program to register a callback function to handle a keyboard when the turtle window has a focus. For example, this call will result in myfun() getting called when the "s" key is pressed:

def myfun():
  print("You pressed s")

turtle.onkey(myfun, "s")
turtle.listen()

But what if I want to handle all keys? I could create a bunch of functions, and register a separate callback for each possible; that's not a great solution. A better solution is to let turtle call a single function when any key is pressed. Fortunately, this is possible by passing None in for the key:

def myfun():
  print("You pressed some key")

turtle.onkey(myfun, None)
turtle.listen()

However: there is no way for myfun to determine which key was pressed. It is called with no parameters, and has no way to recover information about which key was pressed, so this approach is useless. The only way to handle all keyboard events it to call onkey, with a separate handler, for every key you potentially want to handle.

From the source [1] this looks like it was intended that when key is None, turtle would pass a Tkinter event to the handler, so that it could recover information about the event, but this doesn't happen.

[1] https://hg.python.org/cpython/file/3.6/Lib/turtle.py#l700

I would argue that correct behavior is not to expose Tkinter event to users of the higher-level turtle library, but rather to pass the name of the key as a string parameter, so you could write this:

def myfun(key):
  print("You pressed "+key)

turtle.onkey(myfun, None)
turtle.listen()

This is an easy fix and I'd be happy to submit a patch.
History
Date User Action Args
2018-04-27 18:28:41terry.reedysetversions: - Python 2.7, Python 3.4, Python 3.5, Python 3.6, Python 3.7
nosy: + gregorlingl, willingc

components: + Library (Lib), - Tkinter
type: behavior -> enhancement
stage: test needed
2018-04-22 18:34:36je1234create