I am not sure whether it is a bug or not.
I observed the undesirable behavior about the new keyboard class using PsychoPy 2020.1.3 in both Windows and Mac.
Here is a demonstration code.
from psychopy import core, visual
from psychopy.hardware import keyboard
win = visual.Window()
kb = keyboard.Keyboard()
instruction = visual.TextStim(win)
for i in range(5):
# first instruction
instruction.text = 'Press the space key.'
instruction.draw()
win.flip()
key_loop = True
while key_loop:
ptb_keys = kb.getKeys(["space"], waitRelease=False)
if len(ptb_keys):
key_loop = False
# second instruction
instruction.text = 'Press the left or right key.'
instruction.draw()
win.flip()
key_loop = True
while key_loop:
ptb_keys = kb.getKeys(["left", 'right'], waitRelease=False)
if len(ptb_keys):
key_loop = False
It works fine if participants properly follow the instructions.
But, if the participants pressed the left key to the first instruction (this is not a proper response), the second instruction would not be appeared.
Probably, the left key in the keyboard’s queue is remained, and processed as a response to the second instruction.
Am I wrong how to use the new keyboard class?
Have you tried
event.waitKeys()
for keyboard responses? An additional argument allows you to specify what keys are allowed to be used by the participant:
event.waitKeys(keylist=none) #for all keys to be accepted, or
event.waitKeys(keyList=['right','left'] #for only the right and left keys to be accepted
If you don’t like this solution, have you tried
event.clearEvents()
to clear the queue?
1 Like
I found the solution when I made a similar program using the Builder.
I should write the following two lines every time I record responses.
win.callOnFlip(kb.clock.reset) # t=0 on next screen flip
win.callOnFlip(kb.clearEvents, eventType='keyboard') # clear events on next screen flip
Here is the complete running code:
from psychopy import core, visual, data
from psychopy.hardware import keyboard
win = visual.Window()
kb = keyboard.Keyboard()
instruction = visual.TextStim(win)
trials = data.TrialHandler([], 5)
exp = data.ExperimentHandler(name='testExp', dataFileName='exp_results')
exp.addLoop(trials)
for thisTrial in trials:
win.callOnFlip(kb.clock.reset) # t=0 on next screen flip
win.callOnFlip(kb.clearEvents, eventType='keyboard') # clear events on next screen flip
# first instruction
instruction.text = 'Press the space key.'
instruction.draw()
win.flip() # reset the clock to record a response time and clear events
key_loop = True
while key_loop:
ptb_keys = kb.getKeys(["space"], waitRelease=False)
if len(ptb_keys):
trials.addData('choice1', ptb_keys[0].name)
trials.addData('RT1', ptb_keys[0].rt)
key_loop = False
win.callOnFlip(kb.clock.reset) # t=0 on next screen flip
win.callOnFlip(kb.clearEvents, eventType='keyboard') # clear events on next screen flip
# second instruction
instruction.text = 'Press the left or right key.'
instruction.draw()
win.flip() # reset the clock to record a response time and clear events
key_loop = True
while key_loop:
ptb_keys = kb.getKeys(["left", 'right'], waitRelease=False)
if len(ptb_keys):
trials.addData('choice2', ptb_keys[0].name)
trials.addData('RT2', ptb_keys[0].rt)
key_loop = False
exp.nextEntry()
Hey, I tried win.callOnFlip(kb.clearEvents, eventType=‘keyboard’) but it raises an error when executing win.flip:
" ‘NoneType’ object is not callable"…