spacr.qt.widgets.figure_grid_view¶
Display saved and interactive run figures in a scrollable grid.
Saved figures are placed in uniform grid cells and rendered at their original aspect ratios, preserving the geometry of views such as plate heatmaps. The number of columns follows the available panel width, and selecting a tile opens the corresponding figure in the full-size detail view.
Interactive pyqtgraph panels appear as snapshot thumbnails rather than live widgets. This keeps grid resizing responsive while the original widget retains its hover, selection, and restyling behavior on its own tab. Activating a live thumbnail raises that widget. Saved runs and interactive panels use the same collapsible-section and workspace-state mechanisms.
Classes¶
Every figure at once, scrollable, each at its own aspect ratio. |
Functions¶
|
Columns a figure occupies: one, whatever its shape. |
|
How many cells fit across |
|
How the run headings are drawn, minus the colour. |
|
Photograph each pyqtgraph panel, ready for |
Module Contents¶
- class spacr.qt.widgets.figure_grid_view.FigureGridView(parent=None)[source]¶
Bases:
PySide6.QtWidgets.QScrollAreaEvery figure at once, scrollable, each at its own aspect ratio.
- Variables:
figure_activated – emitted with a figure’s index when its cell is clicked, so the caller can open it full size.
figure_menu_requested – emitted with (index, global position) when a cell is right-clicked. The grid holds pictures, not figures, so the menu itself is the caller’s to build – it is the one that still has the matplotlib object.
- Parameters:
parent – parent widget.
Build the scrolling figure grid.
Horizontal scrolling is off: the grid re-flows to the width it is given, so a horizontal bar would mean the re-flow failed rather than that there is more to see.
- Parameters:
parent – parent widget, or
None.
- apply_workspace_state(state) bool[source]¶
Put the arrangement back. Returns whether anything applied.
- Parameters:
state – dict as
workspace_state()returns it, with"collapsed"(list of[label, start]section keys) and"cell_width"(pixels); a non-dict applies nothing.
- is_live_section_collapsed() bool[source]¶
Whether the pyqtgraph tiles are folded away.
Named rather than left to
is_section_collapsed()with two magic arguments: the live section’s key is a constant of this module and a caller repeating(LIVE_SECTION_LABEL, LIVE_SECTION_START)is a caller who can get one of them wrong and silently ask about a section that does not exist.
- is_section_collapsed(label, start) bool[source]¶
Whether this run’s figures are folded away.
- Parameters:
label – the run’s section heading text.
start – index of the run’s first figure; with
labelit identifies the section.
- live_tile_keys() list[source]¶
Return live-panel keys in display order.
Panels without a usable snapshot are omitted, matching
set_live_tiles().
- resizeEvent(event)[source]¶
Re-flow the grid for the new width.
- Parameters:
event – the Qt resize event.
- set_figures(pixmaps, titles=None, sections=None) int[source]¶
Replace the grid contents and return the number of figures added.
- Parameters:
pixmaps (iterable) – Figure images to display.
titles (iterable, optional) – Captions corresponding to
pixmaps.sections (iterable, optional) –
(label, start, count)entries describing runs. Panel lettering restarts within each section.
- set_live_tiles(tiles) int[source]¶
Replace the foldable section of live-panel snapshots.
- Parameters:
tiles (iterable) –
(key, pixmap)or(key, pixmap, title)entries. Activating a tile emits its key throughlive_tile_activated.- Returns:
int – Number of snapshots retained on the grid.
Notes
Entries without a pixmap are omitted. Existing tile widgets are destroyed before the complete set is rebuilt so refreshes cannot stack stale snapshots or retain panels no longer available.
- set_pinned(pixmap, title: str = '') bool[source]¶
A tile that is always first and is not one of the run’s figures.
The tile is a snapshot of the interactive regression graph. Activating it opens the live widget. It occupies a separate slot from
_cellsso persisted figure indices remain aligned withFigureQueue.show_index(); activation usespinned_activatedinstead of a sentinel figure index.Replacing the pinned tile destroys the previous cell before relayout, preventing transparent snapshots from accumulating at the same grid position.
This method updates only the regression tile; other live-panel tiles remain in place. Use
set_live_tiles()to replace the full live section.- Parameters:
pixmap – snapshot
QPixmapof the regression graph;Noneor a null pixmap removes the pinned tile.- Returns:
True when a tile was pinned. A null or missing pixmap removes it.
- set_section_collapsed(label, start, collapsed: bool = True) None[source]¶
Fold a run’s figures away, or bring them back.
- Parameters:
label – the run’s section heading text.
start – index of the run’s first figure; with
labelit identifies the section.
- set_target_cell_width(pixels: int) None[source]¶
How wide a single-width cell should be, before layout.
- Parameters:
pixels – target width in pixels, clamped to
MIN_CELL_PX-MAX_CELL_PX.
- toggle_section(header) bool[source]¶
Reach the run first; fold it away second. Returns the new state.
The console provides the interaction model. A heading that is not already at the top of the viewport is a request to GO THERE, whatever its state – a first click that hid the very section the user was reaching for spends the gesture on the opposite of what it looked like. Only a heading already at the top has nowhere left to navigate to, and there folding is the one thing the gesture can still mean, on a second click exactly where the user’s hand already is.
- Parameters:
header – the clicked section heading; its
section_keynames the section. A header without one does nothing and returnsTrue.
- workspace_state() dict[source]¶
How the grid is ARRANGED, not what is in it.
The figures themselves are files in the run’s own results folder, recorded by the sections that name that folder; copying seventeen PNGs in here would be a second copy of something the run already has. What dies with the process is the arrangement – the tile size the user settled on and which sections they folded away – and a sweep of sixty trials is unusable if that resets.
- spacr.qt.widgets.figure_grid_view.cell_span(aspect: float) int[source]¶
Columns a figure occupies: one, whatever its shape.
- Parameters:
aspect – width / height. Accepted and deliberately ignored – see
CELL_SPAN. Four plates take four slots.
- spacr.qt.widgets.figure_grid_view.cells_across(panel_width: int, target: int = TARGET_CELL_PX) int[source]¶
How many cells fit across
panel_width.Widening the window should show MORE figures, not bigger ones – the opposite of what a stretch-to-fit view does.
- Parameters:
panel_width – available width in pixels; the result is between 1 and 6, and 1 for a width of 0 or less.
- spacr.qt.widgets.figure_grid_view.heading_style() str[source]¶
How the run headings are drawn, minus the colour.
One string, because the chevron and the label are two widgets that have to read as one heading.
A FUNCTION AND NOT A CONSTANT. A module-level string is built once, at import, and so pinned the size to whatever the scale was when the module first loaded – which is exactly the bug this is fixing. Asked for at each use, it follows the interface scale.
- Returns:
the heading stylesheet, without a colour.
- spacr.qt.widgets.figure_grid_view.live_tiles_from_panels(panels) list[source]¶
Photograph each pyqtgraph panel, ready for
set_live_tiles().- Parameters:
panels –
[(key, title, widget)]– the live panels, in the order they should appear. The widget only has to answersnapshot().- Returns:
[(key, pixmap, title)]for the ones that photographed.
Panels whose
snapshot()returnsNoneare omitted rather than shown as empty, nonfunctional tiles. Snapshot errors also omit that panel for the current refresh so an optional preview cannot interrupt the screen.