PsychoPy-Scene
English | 简体中文
A lightweight framework based on the Scene architecture, for PsychoPy.
Features
- Lightweight: Only 2 files, with no additional dependencies
- Type-safe: Supports generics
- Beginner-friendly: You only need to understand the concepts of
ContextandSceneto get started
Installation
pip install psychopy-scene
Quick Start
Context
Context encapsulates data shared across scenes, such as the drawing window Window.
The first step is to create an experiment context.
from psychopy import visual, data
from psychopy_scene import Context
ctx = Context(win=visual.Window(), exp=data.ExperimentHandler())
Scenes
An experiment can be viewed as a composition of a series of scenes. To write an experiment, you only need to:
- Create a scene
- Define its presentation logic
Create a scene using a decorator:
from psychopy import visual
from psychopy.hardware import keyboard
from psychopy_scene.decorator import duration, hardware_keyboard
# create stimulus
stim_1 = visual.TextStim(ctx.win, text="Hello")
stim_2 = visual.TextStim(ctx.win, text="World")
# create scene
@duration(1)
@ctx.scene
def demo_1(color: str, ori: float):
print('it will be called before first flip')
stim_1.color = color
stim_2.ori = ori
return stim_1, stim_2
@close_on('key_space')
@hardware_keyboard()
@ctx.scene
class demo_2:
scene: Scene
def __call__(self, text: str):
stim_1.text = text
return stim_1
def on_key_space(self, evt: keyboard.KeyPress):
self.scene.data['rt'] = evt.tDown - self.scene.data['frame_times'][0]
# show scene
data_1 = demo_1.show(color="red", ori=45)
data_2 = demo_2.show(text="test")
Time-related decorators override one another because they work by setting the scene's timer attribute.
This can be useful in situations where the presentation duration is not fixed:
@duration(1)
@ctx.scene
def demo():
return stim
data = demo.use(duration(0.5)).show()
Data
A scene automatically collects data:
| Name | Description |
|---|---|
| frame_times | Timestamp of each frame flip |
The data can be accessed through scene.data:
@close_on('key_f', 'key_j')
@hardware_keyboard()
@ctx.scene
def demo():
return stim
data = demo.show() # just a dict
show_time = data["frame_times"][0]
Manual data collection is also supported:
@hardware_keyboard()
@ctx.scene
class demo:
scene: Scene
def __call__(self):
return stim
def on_key_f(self, evt: keyboard.KeyPress):
self.scene.data['pressed_duration'] = evt.duration
data = demo.show()
duration = data['pressed_duration']
Events
An event represents a specific time point during scene showing, such as a key press or mouse click.
To execute an action when an event occurs, add a callback for that event:
scene.on('show', lambda _: print('do something'));
These are all the built-in scene events and when they are triggered:
graph TD
Initialization --> s((show)) --> FirstDraw --> f((flipped)) --> c{DrawAgain?}
c -->|No| StopDrawing
c -->|Yes| TimingCheck --> a((frame)) --> Redraw --> p((poll)) --> c
Some event types are provided by decorators associated with input devices. For example, hardware_keyboard provides support for the key_space event, allowing callbacks registered with scene.on('key_space', ...) to be triggered when the space key is pressed.
These decorators trigger other events during the poll event by calling scene.emit('key_space', ...).
Examples
Trial
from psychopy import visual
from psychopy_scene import Context
from psychopy_scene.decorator import duration
def task(ctx: Context, sec=1):
stim = visual.TextStim(ctx.win, text="")
scene = ctx.scene(lambda: stim).use(duration(sec))
data = scene.show()
ctx.record(time=data['frame_times'][0])
Block
from psychopy import visual
from psychopy_scene import Context
from psychopy_scene.decorator import duration
def task(ctx: Context):
stim = visual.TextStim(ctx.win, text="")
scene = ctx.scene(lambda: stim).use(duration(1))
data = scene.show()
ctx.record(time=data['frame_times'][0])
win = visual.Window()
data = []
for block_index in range(10):
ctx = Context(win)
ctx.exp.extraInfo['block_index'] = block_index
task(ctx)
block_data = ctx.exp.getAllEntries()
data.extends(block_data)
Metadata
Release files for psychopy-scene 0.3.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| psychopy_scene-0.3.1.tar.gz | 17.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| psychopy_scene-0.3.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 36.1 kB
Release files / psychopy_scene-0.3.1.tar.gz
| Download URL | psychopy_scene-0.3.1.tar.gz |
|---|---|
| Size | 17.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
11c2d4ba9992499dba788fe3db420141cf03b12ae26031e8417f6848a6cb5efe
|
|
BLAKE2b-256 checksum How to use checksums |
759f6a39620c773052f7df25c7c032428277f260e5c8220d8fdde6f7079e8d6f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 2, 2026.
Transparency logRelease files / psychopy_scene-0.3.1-py3-none-any.whl
| Download URL | psychopy_scene-0.3.1-py3-none-any.whl |
|---|---|
| Size | 18.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
83f82e7f2cfc474c24a2a5b4ae2fab23202650fe4bd4964352541cbc48937034
|
|
BLAKE2b-256 checksum How to use checksums |
205e31101591a385ac1e28f7122e5b75c1cce3bb14a69219ab52fd8c8a8e81b7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 2, 2026.
Transparency log