这类实验有一个特点,就是要呈现的信息要用鼠标点开,并记录被试观看的时间。下面是一个示例,把图片保存成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