The Keyboard in Python

Like the mouse motions and button presses, pressing a key on the keyboard is an event. Like button presses, a key press is a single event with multiple options. The fact that a key has been pressed is an event, and exactly which key it was is a detail, just as it was when a mouse button was pressed. It is important to under­stand that using a standard Python function such as input() will not be successful when trying to read from the keyboard with an event-driven system, although knowing about events can be valuable in understanding how input() could be implemented. When input() is called, it does not return until a line has been read; the keyboard events capture the key press when it occurs. It appears that a call to input() may involve many key press events. What software receives them? That is the important question. The situation is too confusing to be resolved sensibly, so the rule is: never use input() and relatedfunctions when handling key presses. It is acceptable to call print() because it is printing to a console device for which no conflict exists.

Every key press will eventually correspond to a key release, so there are again two events for handling them:

if event.type == pygame.KEYDOWN:

#           A key was depressed.

if event.type == pygame.KEYUP:

#           A key was released.

Which key was it? That’s stored in the variable event.key, but not as a char­acter proper, but as a code. The character “a” is coded as pygame.K_a, and “+” is pygame.K_PLUS. The left arrow key is pygame.K_LEFT. A list of all keys can be found at

https://www.pygame.org/docs/ref/key.html?highlight=keyboard

Code presented here often calls functions keyPressed(k) and keyReleased(k) when the keyboard events occur. The parameter k is the value of the key that was pressed or released.

keyPressed(k): called when a key is pressed. Parameter k is the key that was pressed.

keyReleased(k): called when a key is released. Parameter k is the key that was released.

In an event-driven program, it is unusual for key presses to be converted into strings, as they normally would be in a typical console-style program. That’s be­cause it is expected that the interface to the event-driven program will be through mouse gestures (movements) and using single key commands from the keyboard, like “up arrow” meaning “move forward.”

Example: Pressing a “q” Creates a Random Circle

This program draws a circle at a random location when the “q” key is pressed. The old circles will remain. This illustrates the use of the keyboard in an obvious way. The initialization is to clear the screen and set the background color and fill color. The keyPressed() function generates random x,y coordinates and draws a circle there:

def keyPressed (k):

if k.key == pygame.K q:

pygame.draw.circle(screen, c, (randrange(0,width),randrange(0,height)),30, 3)

The key value is passed as an event rather than the key for a simple reason: Pygame does not decode all keys, but provides an indication of what keys have been pressed. What this means is that there is no uppercase “A;” instead, the sys­tem returns an event that tells us that the “a” key has been pressed and so has a SHIFT key. It is the programmer’s job to determine what this means. That might seem odd, but remember that Pygame was developed for building games. Keys being pressed can mean quite different things within a game than they do in a word processing programs.

So, in the event loop, we do this:

if event.type == pygame.KEYDOWN:

keyPressed(event)

Within the keyPressed function, we can decode this to mean what we wish. Let’s draw a circle when the “+” key is pressed instead of “q.” The “+” key is the “=” key AND a shift, so the function is as follows:

def keyPressed (k):

if k.key == pygame.K EQUALS and k.mod&pygame.KMOD SHIFT:

pygame.draw.circle(screen, c, (randrange(0,width),randrange(0,height)),30, 3)

The keys that can modify the value of another key are referred to as modifiers and are available as a variable event.mod. More than one modifier can be applied at a time: a common example on a PC is CONTROL-ALT-DELETE. All modi­fiers need to be obtainable, so they are specified as specific bits within the mod variable, and bits for all of the applicable modifiers are set. That’s why the expres­sion k.mod&pygame.KMOD_SHIFT was used in the code above. It checks to see if the shift key was depressed, as indicated by the KMOD_SHIFT bit, at the same time as the “=” key was depressed. The result, in this case at least, is “+.”

Example: Reading a Character String

There are some reasons why an event-driven program might wish to read data from the user as a string. Perhaps a name is required, or a key value to ac­cess a database, or a password. Whatever the reason, it should be possible to read a string using the keyboard events passed to keyPressed(). The way it would normally be done is to read one character at a time, and construct a string by concatenation. That’s how this program works:

def keyPressed(k):

global s, t

if k.key == pygame.K_RETURN:

t = s

s = “”

return

if k.key == pygame.K BACKSPACE and len(s)>0:

s = s[:-1]

else:

s = s + chr(k.key)

def draw ():

global s, t

screen.fill((200,200,200))

text (“Enter a string: “, 10, 100, 24, f)

text (s, 20, 130, 24, f)

print(” “, len(s), s)

if (t != “”):

text (“Completed string is “+t, 20, 150, 24, f)

The global variable s holds the string being built, and the string t holds the final string. Characters are captured from the keyboard by keyPressed() and fall into one of three categories:

  1. Most characters are added to the global string s through concatenation. The character passed to keyPressed() is through the The chr() function converts it to a character, which is added to the end of s.
  2. A BACKSPACE deletes the last character typed from the string. This is done using a substring from 0 to the second last character.
  3. A RETURN ends the string. The current string in s is assigned to t, and s is reset to an empty string.

This kind of string data entry is especially useful when entering file names and numeric parameters. There are frequently special interface objects (widgets) that perform these tasks, such as text boxes. Pygame could be used to implement such a widget (see Exercise 6).

Source: Parker James R. (2021), Python: An Introduction to Programming, Mercury Learning and Information; Second edition.

Leave a Reply

Your email address will not be published. Required fields are marked *