plesty.lib.ui ============= .. py:module:: plesty.lib.ui .. autoapi-nested-parse:: GUI framework: one home window, many rearrangeable sub-windows. The framework is generic — a :class:`~plesty.lib.ui.panel.Panel` is anything worth a sub-window, and :class:`~plesty.lib.ui.monitor_panel.MonitorPanel` (live views) is only its first implementation; device controls and run boards are the same contract. :class:`~plesty.lib.ui.theme.Theme` carries the plesty.net design tokens so every PLESTY GUI looks like the platform it belongs to. The Qt-dependent names (:class:`Shell`, :class:`PlotRenderer`, :func:`run`) are resolved lazily, so ``import plesty.lib.ui`` works on a headless host without PySide6 installed; only *using* them requires the ``gui`` extra:: uv add "plesty-lib[gui]" Submodules ---------- .. toctree:: :maxdepth: 1 /reference/plesty/lib/ui/monitor_panel/index /reference/plesty/lib/ui/panel/index /reference/plesty/lib/ui/qt/index /reference/plesty/lib/ui/theme/index Attributes ---------- .. autoapisummary:: plesty.lib.ui.DOCK_AREAS plesty.lib.ui.ASSETS Classes ------- .. autoapisummary:: plesty.lib.ui.MonitorPanel plesty.lib.ui.Panel plesty.lib.ui.Theme Package Contents ---------------- .. py:class:: MonitorPanel(monitor: plesty.lib.monitor.base_monitor.Monitor, *, theme: Optional[plesty.lib.ui.theme.Theme] = None, **kwargs: Any) Bases: :py:obj:`plesty.lib.ui.panel.Panel` Sub-window rendering one monitor. The panel is toolkit-free until it is built: constructing and describing it needs no GUI, which is what lets a headless test cover a shell's composition. Wrap *monitor* into a dockable panel. :param monitor: The live view to render; its name and title become the panel's unless overridden. :param theme: Palette for the plot; ``None`` loads the packaged theme. :param \*\*kwargs: Forwarded to :class:`~plesty.lib.ui.panel.Panel` (``name``, ``title``, ``area``, ``floating``, ``closable``, ``min_width``, ``min_height``). .. py:attribute:: kind :type: ClassVar[str] :value: 'monitor' Panel category, used for layout keys and styling hooks. .. py:attribute:: monitor .. py:attribute:: theme :value: None .. py:attribute:: renderer :type: Any :value: None .. py:method:: build(parent: Any = None) -> Any Create the plot widget and attach it to the monitor. :param parent: The parent widget provided by the shell. :returns: The plot widget. .. py:method:: tick() -> None Drain the monitor's source; every new frame redraws immediately. .. py:method:: status() -> str Return the monitor's status line. :returns: The text the monitor wants shown in the title bar. .. py:method:: close() -> None Detach the renderer and close the monitor's source. .. py:method:: describe() -> dict[str, Any] Return the panel description including the monitor it shows. :returns: The panel's placement plus :meth:`~plesty.lib.monitor.Monitor.describe`. .. py:data:: DOCK_AREAS :type: tuple[str, Ellipsis] :value: ('left', 'right', 'top', 'bottom') .. py:class:: Panel(*, name: Optional[str] = None, title: Optional[str] = None, area: str = 'right', floating: bool = False, closable: bool = True, weight: float = 1.0, min_width: Optional[int] = None, min_height: Optional[int] = None) Bases: :py:obj:`abc.ABC` Base class for the dockable units of a :class:`~plesty.lib.ui.Shell`. Subclasses implement :meth:`build` and usually :meth:`tick`. The panel owns its widget; the shell owns where the widget sits, and remembers that placement between sessions through :attr:`name`. Configure how the shell should place this panel. :param name: Stable identifier used as the layout key; must be unique within a shell. Defaults to the class name. :param title: Title shown in the panel's bar; defaults to *name*. :param area: Initial docking area — one of :data:`DOCK_AREAS`. :param floating: Start as a free-floating window instead of docked. :param closable: Allow the operator to close the panel (it can always be brought back from the shell's Panels menu). :param weight: Share of the area's space this panel starts with, relative to its neighbours: a plot 3, a readout strip 1. Only the initial arrangement — the operator resizes from there, and a saved layout overrides it. :param min_width: Minimum widget width in pixels. :param min_height: Minimum widget height in pixels. :raises ValueError: If *area* is not a known docking area. .. py:attribute:: kind :type: ClassVar[str] :value: 'panel' Panel category, used for layout keys and styling hooks. .. py:attribute:: name :value: 'Panel' .. py:attribute:: title :value: 'Panel' .. py:attribute:: area :value: 'right' .. py:attribute:: floating :value: False .. py:attribute:: closable :value: True .. py:attribute:: weight :value: 1.0 .. py:attribute:: min_width :value: None .. py:attribute:: min_height :value: None .. py:attribute:: _widget :type: Any :value: None .. py:method:: build(parent: Any = None) -> Any :abstractmethod: Create and return the panel's widget. Called once, when the panel is added to a shell. Toolkit imports belong inside this method, so that constructing a panel — and describing it, and testing it — needs no GUI installed. :param parent: The parent widget the shell provides. :returns: The widget to show inside the sub-window. .. py:method:: tick() -> None Advance the panel on the shell's clock. Called at the shell's refresh interval on the GUI thread. Implementations must return quickly: drain a source, redraw, and nothing more. .. py:method:: status() -> str Return the one-line status shown in the panel's title bar. :returns: The status text; empty by default. .. py:method:: close() -> None Release whatever the panel holds; called when the shell shuts down. .. py:property:: widget :type: Any The built widget, or ``None`` before the panel was added to a shell. .. py:method:: ensure_widget(parent: Any = None) -> Any Build the widget on first use and return it. :param parent: The parent widget passed to :meth:`build`. :returns: The panel's widget. .. py:method:: describe() -> dict[str, Any] Return a JSON-serializable description of this panel. :returns: Identity and placement, as stored in a saved layout. .. py:data:: ASSETS :value: 'plesty.lib.ui.assets' .. py:class:: Theme Resolved design tokens plus the stylesheet built from them. :ivar name: Theme identifier, e.g. ``"plesty-dark"``. :ivar tokens: Token name → hex colour. :ivar series: Token names cycled for successive traces of a view. :ivar colormap: Hex stops of the image/heatmap colour map, dark to bright. :ivar state: Semantic state name → token name (running, idle, error, …). .. py:attribute:: name :type: str :value: 'plesty-dark' .. py:attribute:: tokens :type: dict[str, str] .. py:attribute:: series :type: list[str] :value: [] .. py:attribute:: colormap :type: list[str] :value: [] .. py:attribute:: state :type: dict[str, str] .. py:method:: load(palette: Optional[str | pathlib.Path] = None) -> Theme :classmethod: Load the packaged palette, or a custom one from disk. :param palette: Path to a JSON palette with the same keys as the packaged ``palette.json``; ``None`` loads the packaged one. :returns: The resolved theme. .. py:method:: color(token: str, default: Optional[str] = None) -> str Return the hex colour of a design token. :param token: Token name (``"cyan"``, ``"violet"``, ``"muted"``, …) or a literal ``#rrggbb`` value, which is passed through. :param default: Returned when the token is unknown; without it an unknown token resolves to a glaring magenta rather than failing silently mid-experiment. :returns: The hex colour. .. py:method:: series_color(index: int) -> str Return the colour of the *index*-th trace of a view. :param index: Zero-based trace index; wraps around the series list. :returns: The hex colour. .. py:method:: state_color(state: str) -> str Return the colour marking a run or device state. :param state: State name, e.g. ``"running"``, ``"error"``, ``"idle"``. :returns: The hex colour; unknown states fall back to the muted text colour. .. py:method:: stylesheet(source: Optional[str | pathlib.Path] = None) -> str Return the Qt stylesheet with every ``{{token}}`` substituted. :param source: Path to a custom ``.qss`` template; ``None`` uses the packaged ``shell.qss``. :returns: The rendered stylesheet.