Psychopy 脚本因 window 和对话图形用户界面而冻结

Psychopy script freezes with window and dialogue guis

我想要一个显示一堆随机点的实验,然后要求用户输入他们看到的正确点数。我想让实验循环。我可以让它工作 1 次迭代,但是循环有问题,因为 window 和对话发生冲突,或者 window 没有正确关闭。当前 运行 此脚本 Psychopy 时,gui 冻结。我已经用我的代码尝试了 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。如果您有任何建议,请告诉我。谢谢!

通常,您不会使用对话框来收集回复。相反,你会使用 psychopy 刺激来制作在 window 内部起作用的东西。这是一个解决方案:

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