This release is a pre-release and may not be stable for production use.
pycontrol-gui
pycontrol-gui is the Qt desktop frontend for pycontrol-core.
It provides the main pyControl operator workflows:
- Run one task on one setup.
- Edit and run multi-subject experiments.
- Manage setup names, ports, provisioned board identity, and setup variables.
- View live logs and plots.
- Use workspace task handlers, experiment handlers, task plotters, task controls, and addon settings.
Install From PyPI
pyControl is installed once per machine as a global app. Install its lifecycle manager, then install and launch the app:
uv tool install --prerelease if-necessary-or-explicit pycontrol-manager
pycontrol-manager app install
pycontrol-manager app status
pycontrol gui
On first launch, the welcome dialog offers to create or open a workspace.
Or install the app directly:
uv tool install --with-executables-from pycontrol-core pycontrol-gui
# or, in an existing Python environment
pip install --pre pycontrol-gui
Upgrade published packages with pycontrol-manager app update.
Switch the Global App to Development Sources
Given a source root containing sibling pycontrol-core/ and pycontrol-gui/
checkouts:
pycontrol-manager app source local /path/to/source-root
pycontrol gui
Both checkouts are editable, so source edits are immediately live in the same
global commands and OS launcher. pycontrol-manager app update refuses to
replace editable sources. Switch back to the newest published packages
explicitly:
pycontrol-manager app source pypi
For an isolated development environment instead, pycontrol-gui/pyproject.toml
already points uv at the sibling core checkout:
cd /path/to/source-root/pycontrol-gui
uv sync
uv run pycontrol-gui /path/to/workspace
Run tests with Python's module form so stale local script shebangs do not get in the way:
uv run python -m pytest
See maintainability.md for ownership and testing guidance.
Workspaces
Workspaces are plain data folders; the app is installed once and switches
between them. Open a workspace with File -> Open Workspace..., create
one with File -> New Workspace..., or pass a workspace path with
pycontrol gui PATH.
When pycontrol gui is launched without a path, it first searches the current
directory and its parents for a valid workspace. If none is found, it opens the
last valid workspace remembered from an earlier session. If there is no
remembered workspace—such as the first launch from outside a workspace—the
welcome dialog offers to create or open one. Opening or creating a workspace
remembers it for subsequent launches. An explicit path always takes precedence.
pycontrol-gui --set-workspace PATH records the workspace to open on next
launch without starting the GUI;
pycontrol-gui --forget-workspace clears the remembered workspace and recent
list so the next launch shows the welcome dialog again. Use
File -> Reload Workspace to refresh selectors after external file
changes.
The GUI uses the standard pycontrol-core workspace layout:
| Path | GUI use |
|---|---|
tasks/ |
Task selector in Run task and Experiments. |
hardware_definitions/ |
Hardware-definition selector and setup validation. |
devices/ |
Workspace-local device drivers for task sharing and setup maintenance. |
addons/task_handlers/ |
Host-side task automation. |
addons/experiment_handlers/ |
Whole-experiment automation. |
addons/plotters/ |
Custom live plot widgets. |
addons/controls/ |
Declarative or Python task-control panels. |
experiments/*.json |
Experiment editor and run view. |
settings.json / setups.json |
Workspace settings and setup registry. |
Workspace settings.json includes the default data directory plus GUI settings
such as startup tab, plot update frequency, font sizes, and whether task
controls are mounted by default. Relative data paths are resolved against the
workspace root, and users can still override the data directory for an
individual run. GUI application preferences (QSettings) store process-local
state such as the selected workspace root and splitter layouts.
Run Task
The Run task tab connects to one setup, uploads an optional hardware definition, loads a task, starts/stops a session, writes data through core loggers, and routes board events into logs, controls, and plots.
The live log view supports filtering and autoscroll, and task handlers can
publish status snapshots with TaskHandler.update_status(...) for the Run
task and experiment status panels. A Progress value in a snapshot is drawn as
a progress bar, with optional fill and text colours.
Task files can select optional GUI helpers:
v.handler = "sequence"
v.plotter = "SequencePlotter"
v.controls = "reward_panel"
If a helper is missing or fails to load, the task can still run with the default plotter and no custom controls.
Experiments
The Experiments tab edits experiment JSON files and creates one subject panel
per active subject/setup assignment. Each subject panel owns its own
SessionRuntime, SessionController, QThread, QtBusAdapter, logger,
controls, and plot widget so one rig's failure does not directly own another
rig's state.
Experiments can also select an optional hardware-test task. When enabled, the run view uploads and runs that task for each subject before preparing the main experiment task.
An active Run task run (RUNNING) locks the Experiments and Setups tabs. An
open experiment run view locks Run task and Setups so one workflow owns the
shared application state at a time.
The Qt experiment editor exposes hardware definitions as first-class fields. For
tasks that import hardware_definition, the editor shows a hardware-definition
selector (saved to the experiment's hardware_definition field) and the
subjects table previews the effective hwdef per subject. The effective hwdef is
the experiment override, else the setup's hardware_definition default. Run
task offers the same selector, and Setups store a default hwdef per setup.
Addons And Trusted Code
Workspace addons are trusted Python and execute in the GUI process.
- Task plotters live in
addons/plotters/and subclasspycontrol_gui.plotting.TaskPlotter. - Task controls live in
addons/controls/and can be declarative JSON or custom Python widgets exportingbuild_controls(parent, context). The GUI renders JSON specs withTaskControlsPaneland embeds Python widgets directly. - Task and experiment handlers are loaded through
pycontrol-core. SETTINGSdeclarations for task handlers, experiment handlers, and task plotters are edited in the GUI Settings dialog and saved undersettings.addons.*. Task controls are configured through task variables or declarative control defaults instead.- The Settings dialog shows a configurable-file page for built-in plotting
defaults and each addon file with valid
SETTINGS. Each page has aUse defaultsbutton that resets only that file's settings before saving.
Secret settings are masked in the GUI but still saved in settings.json.
Task Sharing And Sandboxes
The Run task tab can export a selected task and its workspace-local dependencies as a protocol bundle ZIP. File -> Switch to Sandbox... opens a sandbox manager that can create an isolated workspace from a shared ZIP, run it against local setups, and return to the parent workspace with a visible sandbox banner. See task-sharing.md.
Plotting Diagnostics
The workspace GUI.plot_update_frequency_hz setting controls live plot redraws;
new workspaces default to 35 Hz. Plot data ingestion still happens through the
session event stream, so lowering the redraw rate reduces GUI paint work without
dropping incoming events.
For hardware performance checks, launch with plot profiling enabled:
PYCONTROL_PLOT_PROFILE=1 pycontrol-gui /path/to/workspace
Set PYCONTROL_PLOT_PROFILE_INTERVAL_S to change the reporting interval. The
GUI logs [plot-profile] lines with call counts plus average and maximum
latency for process_batch() and update_plot() spans.
Import Stability
The supported import surfaces are:
pycontrol_gui.plottingpycontrol_gui.error_loggingpycontrol_gui.resources
Widgets, controllers, and workspace models are application internals. Tests may import them, but downstream code should not treat them as stable.
Error Logging
pycontrol-gui writes host-side diagnostics to a rotating ErrorLog.txt file:
<workspace root>/ErrorLog.txt~/.pycontrol-gui/logs/ErrorLog.txt./ErrorLog.txt
Open Help -> Error Log (Ctrl+E) to inspect or clear the current log.
Run bundles (.pycontrol.zip) are separate and stay in the experiment data
directory.
Documentation
New to the project? Start with the repo-level guides:
- Documentation index - map of everything, with a reading order.
- Architecture tour - learn core and GUI end to end.
- Data-flow walkthrough - one packet's journey through the pipeline.
GUI guides:
- Architecture, threading, and data flow
- Task sharing and sandboxes
- Task plotter addons
- Task controls
- Addons in the GUI
- Maintainability notes
- Changelog
- Contributor workflow
Verify a release installation
Build both repositories with uv build --wheel, then run from this checkout:
uv run python tools/check_wheels.py ../pycontrol-core/dist/pycontrol_core-3.0.0b1-py3-none-any.whl dist/pycontrol_gui-3.0.0b1-py3-none-any.whl
This installs the wheels into a temporary environment and opens/closes a real window with a fresh workspace. Python runs in isolated mode, outside both checkouts. It also checks the minimum core allowed by the GUI metadata; when that is the candidate version, the same installation covers both. For later versions, the minimum is installed from the package index in a second environment. Release core before GUI so the declared minimum is available to installers.
Release files for pycontrol-gui 3.0.0b1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pycontrol_gui-3.0.0b1.tar.gz | 285.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pycontrol_gui-3.0.0b1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 520.4 kB
Release files / pycontrol_gui-3.0.0b1.tar.gz
| Download URL | pycontrol_gui-3.0.0b1.tar.gz |
|---|---|
| Size | 285.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
730fb4fd28a0735bd9ac9f97e6563983d20f26b98c811039b13c7700962fe680
|
|
BLAKE2b-256 checksum How to use checksums |
dda8f8b820f3dde39bb7aa09791c46176774a3ff0b1313ab994428f4c65eea9e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.0
|
Release files / pycontrol_gui-3.0.0b1-py3-none-any.whl
| Download URL | pycontrol_gui-3.0.0b1-py3-none-any.whl |
|---|---|
| Size | 235.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5f4ace070aa68bd69a98441a2ee7008593af952108eedc5d4639e5d05bb7efb1
|
|
BLAKE2b-256 checksum How to use checksums |
a210d4a9ef90296075cfd8390a4900150e65b7e86d97538deb9a3e406eb44dd5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.0
|