PsychoPy Builder: как обновлять экран при каждом нажатии клавиши?

Я хотел бы отображать другой текстовый объект каждый раз, когда субъект нажимает клавишу, в зависимости от того, какая клавиша только что была нажата, и я хотел бы, чтобы только конкретная клавиша переходила к следующему испытанию.

Например, на экране должен отображаться текст, который говорит 5, а затем, если субъект нажмет клавишу «вниз», он изменится на 4, а если он нажмет клавишу «вверх», он изменится на 6 и т. д., но если он нажмет клавишу ввода, мы перейдем к следующему слайду.

Как это сделать?

Что я пробовал до сих пор

Я использовал представление построителя для создания общей структуры, а затем возился с самим кодом отдельно. Я попытался вставить цикл следующим образом:

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()

Если я помещу это в цикл ContinueRoutine подпрограммы, где я хочу такого поведения, я не смогу войти в цикл или какие-либо другие операторы печати для печати, поэтому кажется, что он не входит в цикл. Я пробовал поместить его в несколько других мест, и у меня такие же трудности. Куда бы вы вставили такой цикл, и кажется ли это хорошим способом решить эту проблему?


person Jonas Lindeløv    schedule 01.05.2014    source источник


Ответы (1)


В качестве общего совета: в долгосрочной перспективе вам будет проще добавить его в компонент кода компоновщика. Переход от сборщика к кодеру — это улица с односторонним движением: изменения в коде нельзя вернуть обратно в конструктор. Или вы можете перейти к полному коду, и в этом случае рекомендуется написать его с нуля.

Ваша реализация

Несколько комментариев о причинах, по которым ваш текущий код не работает:

  1. Каждый event.getKeys() будет по умолчанию удалять ответы после его вызова. Таким образом, вызов его несколько раз в каждом кадре, как вы, сделает последующие вызовы пустыми.
  2. event.getKeys() принимает СПИСОК в качестве аргумента, где вы дали ему строку. Если вы хотите прослушать один ключ, дайте ему ['return'], а не «return».

И в качестве совета по улучшению времени (и концептуальной ясности): если визуальное изображение статично во время ожидания нажатия клавиш, я бы просто использовал waitKeys, чтобы что-то происходило только при нажатии клавиш. Это также повысит точность по сравнению с getKeys(), которая привязана к кадрам при включении в цикл с помощью win.flip().

Решение

Таким образом, вы можете сделать следующее в компоненте кода, который должен быть ниже текста:

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()

Переименуйте yourTextStimulus в название вашего текста. Конечно, вы можете настроить это на большее количество / разные клавиши и сделать фактические строки (в настоящее время «5», «7», «2») зависимыми от проб, если вам нужно.

person Jonas Lindeløv    schedule 01.05.2014