# Keyboard events

The Window.on_key_press and Window.on_key_release events are fired when any key on the keyboard is pressed or released, respectively. These events are not affected by "key repeat" -- once a key is pressed there are no more events for that key until it is released.

Both events are parameterised by the same arguments:

    def on_key_press(symbol, modifiers):
        pass

    def on_key_release(symbol, modifiers):
        pass

# Defined key symbols

The symbol argument is an integer that represents a "virtual" key code. It does //not// correspond to any particular numbering scheme; in particular the symbol is //not// an ASCII character code.

pyglet has key symbols that are hardware and platform independent for many types of keyboard. These are defined in pyglet.window.key as constants. For example, the Latin-1 alphabet is simply the letter itself:

    key.A
    key.B
    key.C
    ...

The numeric keys have an underscore to make them valid identifiers:

    key._1
    key._2
    key._3
    ...

Various control and directional keys are identified by name:

    key.ENTER or key.RETURN
    key.SPACE
    key.BACKSPACE
    key.DELETE
    key.MINUS
    key.EQUAL
    key.BACKSLASH

    key.LEFT
    key.RIGHT
    key.UP
    key.DOWN
    key.HOME
    key.END
    key.PAGEUP
    key.PAGEDOWN

    key.F1
    key.F2
    ...

Keys on the number pad have separate symbols:

    key.NUM_1
    key.NUM_2
    ...
    key.NUM_EQUAL
    key.NUM_DIVIDE
    key.NUM_MULTIPLY
    key.NUM_MINUS
    key.NUM_PLUS
    key.NUM_DECIMAL
    key.NUM_ENTER

Some modifier keys have separate symbols for their left and right sides (however they cannot all be distinguished on all platforms):

    key.LCTRL
    key.RCTRL
    key.LSHIFT
    key.RSHIFT
    ...

Key symbols are independent of any modifiers being held down. For example, lower-case and upper-case letters both generate the A symbol. This is also true of the number keypad.

# Modifiers

The modifiers that are held down when the event is generated are combined in a bitwise fashion and provided in the `modifiers` parameter. The modifier constants defined in pyglet.window.key are:

    MOD_SHIFT
    MOD_CTRL
    MOD_ALT         Not available on Mac OS X
    MOD_WINDOWS     Available on Windows only
    MOD_COMMAND     Available on Mac OS X only
    MOD_OPTION      Available on Mac OS X only
    MOD_CAPSLOCK
    MOD_NUMLOCK
    MOD_SCROLLLOCK
    MOD_ACCEL       Equivalent to MOD_CTRL, or MOD_COMMAND on Mac OS X.

For example, to test if the shift key is held down:

    if modifiers & MOD_SHIFT:
        pass

Unlike the corresponding key symbols, it is not possible to determine whether the left or right modifier is held down (though you could emulate this behaviour by keeping track of the key states yourself).

# User-defined key symbols

pyglet does not define key symbols for every keyboard ever made. For example, non-Latin languages will have many keys not recognised by pyglet (however, their Unicode representation will still be valid, see Text and motion events). Even English keyboards often have additional so-called "OEM" keys added by the manufacturer, which might be labelled "Media", "Volume" or "Shopping", for example.

In these cases pyglet will create a key symbol at runtime based on the hardware scancode of the key. This is guaranteed to be unique for that model of keyboard, but may not be consistent across other keyboards with the same labelled key.

The best way to use these keys is to record what the user presses after a prompt, and then check for that same key symbol. Many commercial games have similar functionality in allowing players to set up their own key bindings.

# Remembering key state

pyglet provides the convenience class KeyStateHandler for storing the current keyboard state. This can be pushed onto the event handler stack of any window and subsequently queried as a dict:

    from pyglet.window import key

    window = pyglet.window.Window()
    keys = key.KeyStateHandler()
    window.push_handlers(keys)

    # Check if the spacebar is currently pressed:
    if keys[key.SPACE]:
        pass