Question

I would like to display a different text object each time the subject presses a key depending on which key has just been pressed and I would like only a specific key to advance to the next trial.

For example the screen should display text that says "5" and then if the subject presses the down key it changes to "4" and if they press the up key it changes to "6" etc, but if they press enter we go to the next slide.

How to go about this?

What I have tried so far

I have been using the builder view to create a general framework then have been messing around with the code itself separately afterwards. I tried inserting a loop like this :

inloop=True
while inloop:
    print "in the loop"
    if event.getKeys('return'):
        inloop = False
        continueRoutine=False
    elif event.getKeys('left'):
        print "left key pressed"
    elif event.getKeys('right'):
        print "right key pressed"
    elif event.getKeys('escape'):
         core.quit()

If I put this inside the ContinueRoutine loop of the routine where I want this behavior I am unable to get "in the loop" or any other print statements to print so it seems it is not entering the loop. I have tried putting it a few other places as well and am having similar difficulties. Where would you insert such a loop and does this seem like a good way to go about solving this problem?

Was it helpful?

Solution

As a general advice, it will be easier for you in the long run to add it in a builder code component. Going from builder to coder is a one way street - edits in code cannot be brought back into builder. Or you can go full code in which case it is adviced to write it from scratch.

Your implementation

A few comments on reasons why your current code doesn't work:

  1. Every event.getKeys() will per default delete the responses after it has been called. Thus calling it multiple times in each frame like you do will make the subsequent calls empty.
  2. event.getKeys() takes a LIST as argument where you gave it a string. If you want to listen for a single key, give it ['return'] rather than 'return'.

And as an advice to improve timing (and conceptual clarity): if the visual is static while waiting for keypresses, I would just use waitKeys so something only happens on keypresses. That would also increase the accuracy relative to getKeys() which is locked to frames when put in a loop with win.flip().

Solution

So you could do the following in a code component, which should be below the text:

while True:  # Yes, continue listening forever...
   resp_key = event.waitKeys(keyList=['left','right','up','down','return'])[0]  # pick first and only response.

   # Set different texts dependent on received response
   if resp_key == 'left':
      yourTextStimulus.text = '5'
   elif resp_key == 'right':
      yourTextStimulus.text = '7'
   elif resp_key == 'up':
      yourTextStimulus.text = '2'
   
   # .. or break out of the loop if return was pressed
   elif resp_key == 'return':
      break  # oh, do NOT continue forever... we're finished on return :-)
   # Actually show text if loop was not ended
   yourTextStimulus.draw()
   win.flip()

Rename "yourTextStimulus" to the name of your text. Of course you can tweak this to more/different keys and make the actual strings (currently '5','7','2') trial-dependent if you need to.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top