Скрипт психопии зависает с окном и диалоговым окном
Я хочу эксперимент, который отображает несколько случайных точек, а затем просит пользователя ввести правильное количество точек, которые они видели. Я хочу, чтобы эксперимент повторился. Я могу заставить это работать на 1 итерацию, но что-то не так с циклом, потому что окно и диалог сталкиваются, или окно не закрывается должным образом. При запуске этого скрипта Psychopy в данный момент графический интерфейс зависает. Я пробовал и python3 и python2 с моим кодом.
import random
import psychopy.visual
import psychopy.event
import psychopy.core
from psychopy import gui
import time
while True:
win = psychopy.visual.Window(
size=[500, 500],
units="pix",
fullscr=False
)
myDlg = gui.Dlg(title="Response")
n_dots = random.randint(5, 200)
dot_xys = []
for dot in range(n_dots):
dot_x = random.uniform(-250, 250)
dot_y = random.uniform(-250, 250)
dot_xys.append([dot_x, dot_y])
dot_stim = psychopy.visual.ElementArrayStim(
win=win,
units="pix",
nElements=n_dots,
elementTex=None,
elementMask="circle",
xys=dot_xys,
sizes=10,
contrs=random.random(),
)
dot_stim.draw()
win.flip()
psychopy.event.clearEvents()
time.sleep(4)
win.close()
myDlg.addField('How many dots did you see?')
number = myDlg.show()
if myDlg.OK:
print(number)
myDlg.close()
psychopy.core.quit()
Я использую последнюю версию Psychopy. Пожалуйста, дайте мне знать, если у вас есть какие-либо предложения. Спасибо!
1 ответ
Как правило, вы не будете использовать диалоговое окно для сбора ответов. Скорее, вы бы сделали что-то, что работает внутри окна, используя психопические стимулы. Вот решение:
# Tidy 1: just import from psychopy
import random
from psychopy import visual, event, core
# Tidy 2: create a window once. Don't close it.
win = visual.Window(
size=[500, 500],
units="pix",
fullscr=False
)
instruction_text = visual.TextStim(win, text = u'How many dots did you see?', pos=(0, 100))
answer_text = visual.TextStim(win)
# Solution: a function to collect written responses
def get_typed_answer():
answer_text.text = ''
while True:
key = event.waitKeys()[0]
# Add a new number
if key in '1234567890':
answer_text.text += key
# Delete last character, if there are any chars at all
elif key == 'backspace' and len(answer_text.text) > 0:
answer_text.text = answer_text.text[:-1]
# Stop collecting response and return it
elif key == 'return':
return(answer_text.text)
# Show current answer state
instruction_text.draw()
answer_text.draw()
win.flip()
while True:
# Prepare dot specifications
n_dots = random.randint(5, 200)
dot_xys = []
for dot in range(n_dots):
dot_x = random.uniform(-250, 250)
dot_y = random.uniform(-250, 250)
dot_xys.append([dot_x, dot_y])
# This is extremely ugly! You should generally never create a new stimulus,
# but rather update an existing one. However, ElementArrayStim currently
# does not support changing the number of elements on the go.
dot_stim = visual.ElementArrayStim(
win=win,
units="pix",
elementTex=None,
elementMask="circle",
sizes=10,
contrs=random.random(),
nElements = n_dots,
xys = dot_xys,
)
# Show it
dot_stim.draw()
win.flip()
core.wait(4)
# Collect response
print(get_typed_answer())