psychopy 写类似mouselab的决策实验

这类实验有一个特点,就是要呈现的信息要用鼠标点开,并记录被试观看的时间。下面是一个示例,把图片保存成1.jpg放到同一个文件夹下就可以了。

程序

# -*- coding: utf-8 -*-
"""
Created on Sun Apr 09 18:52:08 2017

@author: zbg
"""

import random
from math import cos, sin, pi
from psychopy.visual import Window, ImageStim, TextStim, BufferImageStim, Rect, Circle, DotStim
from psychopy import core, event, gui, clock
import itertools

pics = ['1']

class Button(object):
    START, END = range(2)
    def __init__(self, win, pos, width, height, name):
        self.name = name
        self.rect = Rect(win, height = height, width = width, units = 'pix', pos = pos)
        self.mouse = event.Mouse(win = win)
        self.caption = TextStim(win, text = u'选择', height = (height - 10) , pos = pos, units = 'pix', color = (0, 0, 0), colorSpace = 'rgb255')
        self.state = self.START
        
    def draw(self):
        x, y = self.mouse.getPos()
        if self.rect.contains(x, y, units = 'pix'):
            self.rect.setLineColor(color = (0, 0, 0), colorSpace = 'rgb255')
            self.caption.setColor(color = (0, 0, 0), colorSpace = 'rgb255')
        else:
            self.rect.setLineColor(color = (255, 255, 255), colorSpace = 'rgb255')
            self.caption.setColor(color = (255, 255, 255), colorSpace = 'rgb255')
        self.rect.draw()
        self.caption.draw()
    
    def process(self):
        x, y = self.mouse.getPos()
        if self.rect.contains(x, y, units = 'pix') and self.mouse.getPressed()[0] == 1:
            self.state = self.END

class Cover(object):
    COVER, SHOW = range(2)
    def __init__(self, win, pos, name, width = 180, height = 60, color = (175, 175, 175)):
        self.name = name
        self.rect = Rect(win, height = height, width = width, units = 'pix', pos = pos)
        self.rect.setFillColor(color = color, colorSpace = 'rgb255')
        self.rect.setLineColor(color = color, colorSpace = 'rgb255')
        self.mouse = event.Mouse(win = win)
        self.state = self.COVER
        self.time = 0
        self.last_state = self.COVER
        self.last_time = 0
        self.clk = clock.Clock()
        
    def draw(self):
        if self.state == self.COVER:
            self.rect.draw()
        elif self.state == self.SHOW:
            pass
    
    def process(self):
        x, y = self.mouse.getPos()
        if self.rect.contains(x, y, units = 'pix') and self.mouse.getPressed()[0] == 1:
            self.state = self.SHOW
        elif not self.rect.contains(x, y, units = 'pix'):
            self.state = self.COVER
        if self.last_state == self.SHOW:
            self.time += self.clk.getTime() - self.last_time
        self.last_state = self.state
        self.last_time = self.clk.getTime()
        
class Trial(object):
    def __init__(self, win, picture, p_file, sub_id):
        self.picture = picture
        self.pic = ImageStim(win, picture + '.png')
        self.buttons = {'left': Button(win, pos = (-240, -260), height = 40, width = 80, name = 'left'),
                        'right': Button(win, pos = ( 240, -260), height = 40, width = 80, name = 'right')}
        self.covers = {'left1': Cover(win, pos = (-240, 100), name = 'left1'),
                       'left2': Cover(win, pos = (-240,-150), name = 'left2'),
                       'right1':Cover(win, pos = ( 240, 100), name = 'right1'),
                       'right2':Cover(win, pos = ( 240, -150), name = 'right2')}
        self.win = win
        self.sub_id = sub_id
        self.p_file = p_file
        
    def run(self):
        done = False
        self.choice = ''
        while not done:
            self.pic.draw()
            for b in self.buttons.values():
                b.process()
                b.draw()
                if b.state == b.END:
                    self.choice = b.name
                    done = True
            for c in self.covers.values():
                c.process()
                c.draw()
            self.win.flip()
        
    def save(self):
        def w(x):
            self.p_file.write(str(x) + '\t')
        map(w, (self.sub_id, self.picture, self.choice, self.covers['left1'].time, self.covers['left2'].time, self.covers['right1'].time, self.covers['right2'].time))
        self.p_file.write('\n')
        
def GetSubject():
    """
    返回被试的id
    """
    myDlg = gui.Dlg(title="Subject Information")
    myDlg.addField(u'被试ID:')
    myDlg.show()

    if myDlg.OK:
        thisInfo = myDlg.data
     
    else:
        exit(0)
        
    return thisInfo[0]
    
sub_id = GetSubject()
p_file = open(sub_id + '.txt', 'w')
p_file.write('id\tpic\tchoice\tleft1\tleft2\tright1\tright2\n')
win = Window(units = 'pix', fullscr = True)
for p in pics:
    trial = Trial(win, picture = p, p_file = p_file, sub_id = sub_id)
    trial.run()
    trial.save()

win.close()

1.jpg

图片大小是960*720像素,图中标注的数字是高度、宽度或者距离,图片用ppt生成的。

运行截图:点开灰色方块后可以看到被遮挡内容并记录观察时间。

更多psychopy程序,尽在:

https://item.taobao.com/item.htm?spm=a230r.1.14.1.QRZDJq&id=530690095131&ns=1&abbucket=6#detail 

转载于:https://my.oschina.net/zbaigao/blog/891366

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值