psychopy 2025.1.1__py3-none-any.whl → 2025.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of psychopy might be problematic. Click here for more details.
- psychopy/VERSION +1 -1
- psychopy/alerts/alertsCatalogue/4810.yaml +19 -0
- psychopy/alerts/alertsCatalogue/alertCategories.yaml +4 -0
- psychopy/alerts/alertsCatalogue/alertmsg.py +15 -1
- psychopy/alerts/alertsCatalogue/generateAlertmsg.py +2 -2
- psychopy/app/Resources/classic/add_many.png +0 -0
- psychopy/app/Resources/classic/add_many@2x.png +0 -0
- psychopy/app/Resources/classic/devices.png +0 -0
- psychopy/app/Resources/classic/devices@2x.png +0 -0
- psychopy/app/Resources/classic/photometer.png +0 -0
- psychopy/app/Resources/classic/photometer@2x.png +0 -0
- psychopy/app/Resources/dark/add_many.png +0 -0
- psychopy/app/Resources/dark/add_many@2x.png +0 -0
- psychopy/app/Resources/dark/devices.png +0 -0
- psychopy/app/Resources/dark/devices@2x.png +0 -0
- psychopy/app/Resources/dark/photometer.png +0 -0
- psychopy/app/Resources/dark/photometer@2x.png +0 -0
- psychopy/app/Resources/light/add_many.png +0 -0
- psychopy/app/Resources/light/add_many@2x.png +0 -0
- psychopy/app/Resources/light/devices.png +0 -0
- psychopy/app/Resources/light/devices@2x.png +0 -0
- psychopy/app/Resources/light/photometer.png +0 -0
- psychopy/app/Resources/light/photometer@2x.png +0 -0
- psychopy/app/_psychopyApp.py +35 -13
- psychopy/app/builder/builder.py +88 -35
- psychopy/app/builder/dialogs/__init__.py +69 -220
- psychopy/app/builder/dialogs/dlgsCode.py +29 -8
- psychopy/app/builder/dialogs/paramCtrls.py +1468 -904
- psychopy/app/builder/validators.py +25 -17
- psychopy/app/coder/coder.py +12 -1
- psychopy/app/coder/repl.py +5 -2
- psychopy/app/colorpicker/__init__.py +1 -1
- psychopy/app/deviceManager/__init__.py +1 -0
- psychopy/app/deviceManager/addDialog.py +218 -0
- psychopy/app/deviceManager/dialog.py +185 -0
- psychopy/app/deviceManager/panel.py +191 -0
- psychopy/app/deviceManager/utils.py +60 -0
- psychopy/app/idle.py +7 -0
- psychopy/app/locale/ar_001/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ar_001/LC_MESSAGE/messages.po +12695 -10592
- psychopy/app/locale/cs_CZ/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/cs_CZ/LC_MESSAGE/messages.po +10199 -24
- psychopy/app/locale/da_DK/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/da_DK/LC_MESSAGE/messages.po +10199 -24
- psychopy/app/locale/de_DE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/de_DE/LC_MESSAGE/messages.po +11221 -9712
- psychopy/app/locale/el_GR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/el_GR/LC_MESSAGE/messages.po +10200 -25
- psychopy/app/locale/en_NZ/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/en_NZ/LC_MESSAGE/messages.po +10200 -25
- psychopy/app/locale/en_US/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/en_US/LC_MESSAGE/messages.po +10195 -18
- psychopy/app/locale/es_CO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_CO/LC_MESSAGE/messages.po +11917 -9101
- psychopy/app/locale/es_ES/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_ES/LC_MESSAGE/messages.po +11924 -9103
- psychopy/app/locale/es_US/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_US/LC_MESSAGE/messages.po +11917 -9101
- psychopy/app/locale/et_EE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/et_EE/LC_MESSAGE/messages.po +11084 -9569
- psychopy/app/locale/fa_IR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fa_IR/LC_MESSAGE/messages.po +11590 -5806
- psychopy/app/locale/fi_FI/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fi_FI/LC_MESSAGE/messages.po +10199 -24
- psychopy/app/locale/fr_FR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fr_FR/LC_MESSAGE/messages.po +11091 -9577
- psychopy/app/locale/he_IL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/he_IL/LC_MESSAGE/messages.po +11072 -9549
- psychopy/app/locale/hi_IN/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/hi_IN/LC_MESSAGE/messages.po +11071 -9559
- psychopy/app/locale/hu_HU/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/hu_HU/LC_MESSAGE/messages.po +10200 -25
- psychopy/app/locale/it_IT/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/it_IT/LC_MESSAGE/messages.po +11072 -9560
- psychopy/app/locale/ja_JP/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ja_JP/LC_MESSAGE/messages.po +1485 -1137
- psychopy/app/locale/ko_KR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ko_KR/LC_MESSAGE/messages.po +10199 -24
- psychopy/app/locale/ms_MY/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ms_MY/LC_MESSAGE/messages.po +11463 -8757
- psychopy/app/locale/nl_NL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/nl_NL/LC_MESSAGE/messages.po +10200 -25
- psychopy/app/locale/nn_NO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/nn_NO/LC_MESSAGE/messages.po +10200 -25
- psychopy/app/locale/pl_PL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/pl_PL/LC_MESSAGE/messages.po +10200 -25
- psychopy/app/locale/pt_PT/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/pt_PT/LC_MESSAGE/messages.po +11288 -9434
- psychopy/app/locale/ro_RO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ro_RO/LC_MESSAGE/messages.po +10200 -25
- psychopy/app/locale/ru_RU/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ru_RU/LC_MESSAGE/messages.po +10199 -24
- psychopy/app/locale/sv_SE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/sv_SE/LC_MESSAGE/messages.po +11441 -8747
- psychopy/app/locale/tr_TR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/tr_TR/LC_MESSAGE/messages.po +11069 -9545
- psychopy/app/locale/zh_CN/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/zh_CN/LC_MESSAGE/messages.po +12085 -8268
- psychopy/app/locale/zh_TW/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/zh_TW/LC_MESSAGE/messages.po +11929 -8022
- psychopy/app/plugin_manager/dialog.py +12 -3
- psychopy/app/plugin_manager/packageIndex.py +303 -0
- psychopy/app/plugin_manager/packages.py +203 -63
- psychopy/app/plugin_manager/plugins.py +120 -240
- psychopy/app/preferencesDlg.py +6 -1
- psychopy/app/psychopyApp.py +16 -4
- psychopy/app/runner/runner.py +10 -2
- psychopy/app/runner/scriptProcess.py +8 -3
- psychopy/app/stdout/stdOutRich.py +11 -4
- psychopy/app/themes/icons.py +3 -0
- psychopy/app/utils.py +61 -0
- psychopy/data/experiment.py +133 -23
- psychopy/data/routine.py +12 -0
- psychopy/data/staircase.py +42 -20
- psychopy/data/trial.py +20 -12
- psychopy/data/utils.py +42 -2
- psychopy/demos/builder/Experiments/dragAndDrop/drag_and_drop.psyexp +22 -5
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solutions.xlsx +0 -0
- psychopy/demos/builder/Experiments/stroopVoice/stroopVoice.psyexp +2 -12
- psychopy/demos/builder/Feature Demos/buttonBox/buttonBoxDemo.psyexp +3 -8
- psychopy/demos/builder/Feature Demos/movies/movie.psyexp +220 -0
- psychopy/demos/builder/Feature Demos/movies/readme.md +3 -0
- psychopy/demos/builder/Feature Demos/visualValidator/visualValidator.psyexp +1 -2
- psychopy/demos/builder/Hardware/camera/camera.psyexp +3 -16
- psychopy/demos/builder/Hardware/microphone/microphone.psyexp +3 -16
- psychopy/demos/coder/hardware/hdf5_extract.py +133 -0
- psychopy/event.py +20 -15
- psychopy/experiment/_experiment.py +86 -10
- psychopy/experiment/components/__init__.py +3 -10
- psychopy/experiment/components/_base.py +9 -20
- psychopy/experiment/components/button/__init__.py +1 -1
- psychopy/experiment/components/buttonBox/__init__.py +50 -54
- psychopy/experiment/components/camera/__init__.py +137 -359
- psychopy/experiment/components/keyboard/__init__.py +17 -24
- psychopy/experiment/components/microphone/__init__.py +61 -110
- psychopy/experiment/components/movie/__init__.py +2 -3
- psychopy/experiment/components/serialOut/__init__.py +192 -93
- psychopy/experiment/components/settings/__init__.py +45 -27
- psychopy/experiment/components/sound/__init__.py +82 -73
- psychopy/experiment/components/soundsensor/__init__.py +43 -80
- psychopy/experiment/devices.py +303 -0
- psychopy/experiment/exports.py +20 -18
- psychopy/experiment/flow.py +7 -0
- psychopy/experiment/loops.py +47 -29
- psychopy/experiment/monitor.py +74 -0
- psychopy/experiment/params.py +48 -10
- psychopy/experiment/plugins.py +28 -108
- psychopy/experiment/py2js_transpiler.py +1 -1
- psychopy/experiment/routines/__init__.py +1 -1
- psychopy/experiment/routines/_base.py +59 -24
- psychopy/experiment/routines/audioValidator/__init__.py +19 -155
- psychopy/experiment/routines/visualValidator/__init__.py +25 -25
- psychopy/hardware/__init__.py +20 -57
- psychopy/hardware/button.py +15 -2
- psychopy/hardware/camera/__init__.py +2237 -1394
- psychopy/hardware/joystick/__init__.py +1 -1
- psychopy/hardware/keyboard.py +5 -8
- psychopy/hardware/listener.py +4 -1
- psychopy/hardware/manager.py +75 -35
- psychopy/hardware/microphone.py +52 -6
- psychopy/hardware/monitor.py +144 -0
- psychopy/hardware/photometer/__init__.py +156 -117
- psychopy/hardware/serialdevice.py +16 -2
- psychopy/hardware/soundsensor.py +4 -1
- psychopy/iohub/devices/deviceConfigValidation.py +2 -1
- psychopy/iohub/devices/keyboard/darwin.py +8 -5
- psychopy/iohub/util/__init__.py +7 -8
- psychopy/localization/generateTranslationTemplate.py +208 -116
- psychopy/localization/messages.pot +4305 -3502
- psychopy/monitors/MonitorCenter.py +174 -74
- psychopy/plugins/__init__.py +6 -4
- psychopy/preferences/devices.py +80 -0
- psychopy/preferences/generateHints.py +2 -1
- psychopy/preferences/preferences.py +35 -11
- psychopy/scripts/psychopy-pkgutil.py +969 -0
- psychopy/scripts/psyexpCompile.py +1 -1
- psychopy/session.py +34 -38
- psychopy/sound/__init__.py +6 -260
- psychopy/sound/audioclip.py +164 -0
- psychopy/sound/backend_ptb.py +8 -0
- psychopy/sound/backend_pygame.py +10 -0
- psychopy/sound/backend_pysound.py +9 -0
- psychopy/sound/backends/__init__.py +0 -0
- psychopy/sound/microphone.py +3 -0
- psychopy/sound/sound.py +58 -0
- psychopy/tests/data/correctScript/python/correctNoiseStimComponent.py +1 -1
- psychopy/tests/data/duplicateHeaders.csv +2 -0
- psychopy/tests/test_app/test_builder/test_BuilderFrame.py +22 -7
- psychopy/tests/test_app/test_builder/test_CompileFromBuilder.py +0 -2
- psychopy/tests/test_data/test_utils.py +5 -1
- psychopy/tests/test_experiment/test_components/test_ButtonBoxComponent.py +22 -2
- psychopy/tests/test_hardware/test_ports.py +0 -12
- psychopy/tests/test_tools/test_stringtools.py +1 -1
- psychopy/tools/attributetools.py +12 -5
- psychopy/tools/fontmanager.py +17 -14
- psychopy/tools/movietools.py +43 -2
- psychopy/tools/stringtools.py +33 -8
- psychopy/tools/versionchooser.py +1 -1
- psychopy/validation/audio.py +5 -1
- psychopy/validation/visual.py +5 -1
- psychopy/visual/basevisual.py +8 -7
- psychopy/visual/circle.py +2 -2
- psychopy/visual/image.py +29 -109
- psychopy/visual/movies/__init__.py +1800 -313
- psychopy/visual/polygon.py +4 -0
- psychopy/visual/shape.py +2 -2
- psychopy/visual/window.py +34 -11
- psychopy/voicekey/__init__.py +41 -669
- psychopy/voicekey/labjack_vks.py +7 -48
- psychopy/voicekey/parallel_vks.py +7 -42
- psychopy/voicekey/vk_tools.py +114 -263
- {psychopy-2025.1.1.dist-info → psychopy-2025.2.1.dist-info}/METADATA +17 -11
- {psychopy-2025.1.1.dist-info → psychopy-2025.2.1.dist-info}/RECORD +216 -184
- {psychopy-2025.1.1.dist-info → psychopy-2025.2.1.dist-info}/WHEEL +1 -1
- psychopy/visual/movies/players/__init__.py +0 -62
- psychopy/visual/movies/players/ffpyplayer_player.py +0 -1401
- psychopy/voicekey/demo_vks.py +0 -12
- psychopy/voicekey/signal.py +0 -42
- {psychopy-2025.1.1.dist-info → psychopy-2025.2.1.dist-info}/entry_points.txt +0 -0
- {psychopy-2025.1.1.dist-info → psychopy-2025.2.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
4
|
from pathlib import Path
|
|
5
|
+
from psychopy.preferences import prefs
|
|
5
6
|
from psychopy.alerts._alerts import alert
|
|
6
7
|
from psychopy.experiment import Param
|
|
7
|
-
from psychopy.experiment.plugins import PluginDevicesMixin
|
|
8
|
+
from psychopy.experiment.plugins import PluginDevicesMixin
|
|
8
9
|
from psychopy.experiment.components import getInitVals
|
|
9
10
|
from psychopy.experiment.routines import Routine, BaseValidatorRoutine
|
|
11
|
+
from psychopy.experiment.devices import DeviceBackend
|
|
10
12
|
from psychopy.localization import _translate
|
|
11
13
|
|
|
12
14
|
|
|
@@ -23,6 +25,10 @@ class VisualValidatorRoutine(BaseValidatorRoutine, PluginDevicesMixin):
|
|
|
23
25
|
)
|
|
24
26
|
deviceClasses = []
|
|
25
27
|
version = "2025.1.0"
|
|
28
|
+
legacyParams = [
|
|
29
|
+
# old device setup params, no longer needed as this is handled by DeviceManager
|
|
30
|
+
"deviceBackend"
|
|
31
|
+
]
|
|
26
32
|
|
|
27
33
|
def __init__(
|
|
28
34
|
self,
|
|
@@ -124,24 +130,17 @@ class VisualValidatorRoutine(BaseValidatorRoutine, PluginDevicesMixin):
|
|
|
124
130
|
"deviceBackend",
|
|
125
131
|
"channel",
|
|
126
132
|
]
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
allowedLabels=self.getBackendLabels,
|
|
139
|
-
label=_translate("Light sensor type"),
|
|
140
|
-
hint=_translate(
|
|
141
|
-
"Type of light sensor to use."
|
|
142
|
-
),
|
|
143
|
-
direct=False
|
|
144
|
-
)
|
|
133
|
+
# label to refer to device by
|
|
134
|
+
def getDeviceLabels():
|
|
135
|
+
# start with none
|
|
136
|
+
labels = []
|
|
137
|
+
# iterate through saved devices
|
|
138
|
+
for name, profile in prefs.devices.items():
|
|
139
|
+
# if device is the correct type, include it
|
|
140
|
+
if profile.get("deviceClass", None) in self.deviceClasses:
|
|
141
|
+
labels.append(name)
|
|
142
|
+
|
|
143
|
+
return labels
|
|
145
144
|
self.params['channel'] = Param(
|
|
146
145
|
channel, valType="code", inputType="single", categ="Device",
|
|
147
146
|
label=_translate("Light sensor channel"),
|
|
@@ -152,8 +151,6 @@ class VisualValidatorRoutine(BaseValidatorRoutine, PluginDevicesMixin):
|
|
|
152
151
|
)
|
|
153
152
|
)
|
|
154
153
|
|
|
155
|
-
self.loadBackends()
|
|
156
|
-
|
|
157
154
|
def writeDeviceCode(self, buff):
|
|
158
155
|
"""
|
|
159
156
|
Code to setup the CameraDevice for this component.
|
|
@@ -367,10 +364,9 @@ class ScreenBufferVisualValidatorBackend(DeviceBackend):
|
|
|
367
364
|
example for implementing other light sensor device backends.
|
|
368
365
|
"""
|
|
369
366
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
deviceClasses = ["psychopy.hardware.lightsensor.ScreenBufferSampler"]
|
|
367
|
+
backendLabel = "Screen Buffer Sampler (Debug)"
|
|
368
|
+
deviceClass = "psychopy.hardware.lightsensor.ScreenBufferSampler"
|
|
369
|
+
icon = "light/visual_validator.png"
|
|
374
370
|
|
|
375
371
|
def getParams(self: VisualValidatorRoutine):
|
|
376
372
|
# define order
|
|
@@ -397,3 +393,7 @@ class ScreenBufferVisualValidatorBackend(DeviceBackend):
|
|
|
397
393
|
")\n"
|
|
398
394
|
)
|
|
399
395
|
buff.writeOnceIndentedLines(code % inits)
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
# register backend with Component
|
|
399
|
+
VisualValidatorRoutine.registerBackend(ScreenBufferVisualValidatorBackend)
|
psychopy/hardware/__init__.py
CHANGED
|
@@ -110,9 +110,9 @@ def getPhotometerByName(name):
|
|
|
110
110
|
we were unable to find it.
|
|
111
111
|
|
|
112
112
|
"""
|
|
113
|
-
for photom in getAllPhotometers():
|
|
113
|
+
for thisName, photom in getAllPhotometers().items():
|
|
114
114
|
# longName is used from the GUI and driverFor is for coders
|
|
115
|
-
if name.lower()
|
|
115
|
+
if name.lower() == thisName:
|
|
116
116
|
return photom
|
|
117
117
|
|
|
118
118
|
|
|
@@ -154,61 +154,24 @@ def findPhotometer(ports=None, device=None):
|
|
|
154
154
|
print(photom.getSpectrum())
|
|
155
155
|
|
|
156
156
|
"""
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
photom = None
|
|
176
|
-
logging.info('scanning serial ports...')
|
|
177
|
-
logging.flush()
|
|
178
|
-
for thisPort in ports:
|
|
179
|
-
logging.info('...{}'.format(thisPort))
|
|
180
|
-
logging.flush()
|
|
181
|
-
for Photometer in photometers:
|
|
182
|
-
# Looks like we got an invalid photometer, carry on
|
|
183
|
-
if Photometer is None:
|
|
184
|
-
continue
|
|
185
|
-
try:
|
|
186
|
-
photom = Photometer(port=thisPort)
|
|
187
|
-
except Exception as ex:
|
|
188
|
-
msg = "Couldn't initialize photometer {0}: {1}"
|
|
189
|
-
logging.error(msg.format(Photometer.__name__, ex))
|
|
190
|
-
# We threw an exception so we should just skip ahead
|
|
191
|
-
continue
|
|
192
|
-
if photom.OK:
|
|
193
|
-
logging.info(' ...found a %s\n' % (photom.type))
|
|
194
|
-
logging.flush()
|
|
195
|
-
# we're now sure that this is the correct device and that
|
|
196
|
-
# it's configured now increase the number of attempts made
|
|
197
|
-
# to communicate for temperamental devices!
|
|
198
|
-
if hasattr(photom, 'setMaxAttempts'):
|
|
199
|
-
photom.setMaxAttempts(10)
|
|
200
|
-
# we found one so stop looking
|
|
201
|
-
return photom
|
|
202
|
-
else:
|
|
203
|
-
if photom.com and photom.com.isOpen:
|
|
204
|
-
logging.info('closing port')
|
|
205
|
-
photom.com.close()
|
|
206
|
-
|
|
207
|
-
# If we got here we didn't find one
|
|
208
|
-
logging.info('...nope!\n\t')
|
|
209
|
-
logging.flush()
|
|
210
|
-
|
|
211
|
-
return None
|
|
157
|
+
from .photometer import getAllPhotometerClasses
|
|
158
|
+
# try each port
|
|
159
|
+
if isinstance(ports, str) or ports is None:
|
|
160
|
+
ports = [ports]
|
|
161
|
+
for port in ports:
|
|
162
|
+
# get all available devices
|
|
163
|
+
for cls, profiles in DeviceManager.getAvailableDevices(
|
|
164
|
+
list(getAllPhotometerClasses().values())
|
|
165
|
+
).items():
|
|
166
|
+
# iterate through each
|
|
167
|
+
for profile in profiles:
|
|
168
|
+
# if port matches, or device matches and no port given, initialise from this profile
|
|
169
|
+
if (
|
|
170
|
+
port is None and device == cls.__name__
|
|
171
|
+
) or (
|
|
172
|
+
port and "port" in profile and profile['port'] in port
|
|
173
|
+
):
|
|
174
|
+
return DeviceManager.addDevice(**profile)
|
|
212
175
|
|
|
213
176
|
|
|
214
177
|
if __name__ == "__main__":
|
psychopy/hardware/button.py
CHANGED
|
@@ -29,6 +29,13 @@ class ButtonResponse(base.BaseResponse):
|
|
|
29
29
|
# match an integer to channel
|
|
30
30
|
if isinstance(other, int):
|
|
31
31
|
return other == self.channel
|
|
32
|
+
# match a dict by converting it to a ButtonResponse, if possible
|
|
33
|
+
if isinstance(other, dict):
|
|
34
|
+
try:
|
|
35
|
+
return ButtonResponse(**other) == self
|
|
36
|
+
except:
|
|
37
|
+
# if it can't instantiate a ButtonResponse, it's not the same as this
|
|
38
|
+
return False
|
|
32
39
|
|
|
33
40
|
return False
|
|
34
41
|
|
|
@@ -188,6 +195,9 @@ class ButtonBox:
|
|
|
188
195
|
Builder-friendly wrapper around BaseButtonGroup.
|
|
189
196
|
"""
|
|
190
197
|
def __init__(self, device):
|
|
198
|
+
# start off with None for device
|
|
199
|
+
self.device = None
|
|
200
|
+
|
|
191
201
|
if isinstance(device, BaseButtonGroup):
|
|
192
202
|
# if given a button group, use it
|
|
193
203
|
self.device = device
|
|
@@ -198,10 +208,13 @@ class ButtonBox:
|
|
|
198
208
|
else:
|
|
199
209
|
# don't use formatted string literals in _translate()
|
|
200
210
|
raise ValueError(_translate(
|
|
201
|
-
"Could not find device named '{
|
|
211
|
+
"Could not find device named '{}', make sure it has been set up "
|
|
202
212
|
"in DeviceManager."
|
|
203
213
|
).format(device))
|
|
204
|
-
|
|
214
|
+
# if given None, use first button group we find in DeviceManager
|
|
215
|
+
for name, device in DeviceManager.getInitialisedDevices(BaseButtonGroup).items():
|
|
216
|
+
self.device = device
|
|
217
|
+
break
|
|
205
218
|
# starting value for status (Builder)
|
|
206
219
|
self.status = constants.NOT_STARTED
|
|
207
220
|
# arrays to store info (Builder)
|