# PsychoPy踩坑指南

最近在研究一个SSVEP视觉刺激实验,使用了psychopy来呈现画面,这个神人库也是bug有一堆。

# 故做如下记录

# 1.事件循环机制极其垃圾

这个库的核心的事件循环线程是不会自动回收的,必须要手动core.quit()才能回收。如果你在所有窗口都关闭之前就退出事件循环,那窗口会直接卡死再也无法响应,必须得taskkill,即使是用Ctrl+C强制结束进程后这个未响应窗口仍会一直存在着,这个快捷键仅仅只是释放了终端光标而已。

另外,如果有什么耗时操作占着主线程,窗口也会未响应。当然我指的不是同步阻塞,而是基于asyncio的异步任务,总之只要任何一个耗时任务在运行,就会卡他的事件循环,不知道是特意设计还是啥问题。

# 1-1.渲染机制很奇怪

不知道为什么,我的一个脑控无人机项目在使用这个库做SSVEP视觉刺激时,特定情况下帧率会特别低完全不符合闪烁需求。

这里的 “特定需求” 指的是使用神舞科技NeuroAI软件记录脑电波时。倘若没有开始记录只是开始运行刺激闪烁是完全没问题的,此时是返回的随机数据做测试。但是开始记录后就会导致flip()函数的返回所需时间特别久,闪烁帧率远低于显示器额定帧率,盲猜是读脑电的线程解析运算量太大,卡了GIL,可惜这个猜测是错的。就算在解析线程加了core.wait()或者time.sleep(),仍然帧率很低。然而把两个模块分进程运行就完全没问题了。说明仍然是GIL的问题,但是cpu被释放了,flip()仍然返回很慢?只有天知道是为什么,这个神人库甚至有能力超脱GIL之外。

# 2.模块组织得极其混乱

不管用哪个打包器(我试过pyinstallernuitkacx_Freeze)都无法直接正确分析出来psychopy的依赖树,手动添加了很多根本没用到的隐藏依赖。

其次,导入耗时非常长,很多并不是核心功能的模块被隐式加载了实际上没用到。

# 3.类型定义缺失 不注重类型安全

visual.Window这个类是有一个构造参数叫winType的(使用的渲染后端类型,可以用pyglet/GLFW/pygame),但是根本没有写泛型来声明窗口句柄的具体类型,这是一个例子,这个库几乎所有字段的类型都是Any | Unknown | None,根本过不了静态类型检查。

# 4.API改来改去,破坏性更新随随便便就发到Release

忘记哪天了。写的一个flip()渲染SSVEP刺激块窗口,有个字段叫frames(功能不重要),上午是正常的,下午就报错说窗口基类的代码里用了这个字段,很显然就是这个库新版本搞了个会破坏用户代码的更新。一猜就知道是uv自动更新搞的。

# 5.解释器兼容性及其差,向下不兼容3.10-,向上不兼容3.11+

我们WRC团队的分析电脑装的python版本都不一样,有些设备装的上有些设备装不上,最后还是统一换3.11.0解决的,浪费时间,不是什么大问题,高版本不兼容就不说什么了因为有很多破坏性更新,为什么低版本也不兼容。