How to detect asynchronously whether a key is pressed?

I am trying to fade a grating continuously while a key is held down.

I have the following in Each Frame:

key = event.getKeys()
if key:
    c = c - 0.01
    grating.contrast = c

However, only one keypress is registered, nothing further happens while the key is held down.

Could I ask for some help understanding this? I thought that getKeys would check asychronously whether a key was down. However, it doesn’t register another keypress until I release the key and press it again.

I also tried:

key = kb.getKeys(['right'], waitRelease=False)

However the same behaviour occurred.

After reviewing some similar threads, I also tried

keys = kb.getKeys(['right'], waitRelease=False, clear=False)
keys2 = kb.getKeys(['right'], waitRelease=True, clear=True)

however, this leads to the grating fading all the way as soon as a key is pressed and released (I suppose because the key event is not cleared and keeps firing on every frame).

Am I missing something here?


Here is an example Visual analog scale: press and hold key that might help. There is also an example in the demo experiments that works in a similar way.

Best wishes, Jens

I’ve just written a demo for this which might be useful

Key Down code | try it

Compares the length of two keyboard components (one detecting key presses and the other key releases) to determine whether a key is currently pressed down.

The right way to look at this is that GetKeys simply tells you what keyboard events (presses or releases) are in the keyboard buffer - it is up to you to track whether keys are actually up or down in Every Frame:

keys = mykb.getKeys(keysWatched, waitRelease = False, clear = False)

if len(keys):# if a key has been pressed
    for k in keys:
    for i, key in enumerate(keysWatched):
        if keys[-1].name == 'left':
            if keys[-1].duration:
                left_down = False
                left_down = True
        if keys[-1].name == 'right':
            if keys[-1].duration:
                right_down = False
                right_down = True

if left_down:
    contrast -= 0.1
    grating.contrast = contrast
if right_down:
    contrast += 0.1
    grating.contrast = contrast

and in Begin Routine:

contrast = 1

mykb = keyboard.Keyboard()
left_down = False
right_down = False

keysWatched=['left', 'right']

status =['up']