spacr.qt.widgets.preview_scale

One scale slider per live preview, scaling that preview alone (item 471).

The whole-GUI scale (spacr.qt.gui_scale) is fixed at startup and applies everywhere. A preview wants its own: a Mask preview on a laptop may need to shrink its controls to give the images room, while the settings beside it stay readable. Every preview – Mask, Measure, Plaque, Timelapse, Motility and the image-UMAP views – installs the same control through install_preview_scale(), so there is one implementation of it.

WHAT IT SCALES, LIVE, WITHOUT A RESTART. Everything inside the preview that spaCR sized in pixels:

  • style-sheet sizes – font sizes, paddings, margins, minimum and maximum widths and heights, radii – both the ones the preview inherits from the application sheet and the ones its widgets set on themselves. Border widths are left alone, so a 1 px rule stays a rule;

  • minimum, maximum and fixed widget sizes set in code;

  • layout margins and spacing;

  • button icon sizes;

  • and, through PreviewScaler.add_hook(), what only the panel knows how to redraw: Measure’s crop thumbnails, a matplotlib figure’s dots and labels (scale_figure_canvas()).

Each value’s own base is remembered on the widget, so scaling is always from the size the code asked for and never compounds. A size the code sets again later becomes the new base. At 100 % nothing is touched at all – no sheet, no size, no property – so a preview at its default scale is the preview it was before this module existed.

The slider itself is exempt: at 10 % the thing that brings the preview back must still be there to grab, and double-clicking its value returns to 100 %. Ctrl+Alt+0 resets every preview (reset_all_preview_scales()).

A WINDOW OPENED FROM THE PREVIEW IS NOT THE PREVIEW (item 522). A dialog parented to the panel is a window of its own, yet Qt cascades the panel’s scaled sheet into it, and the walk found it among the panel’s children: at 150 % a settings dialog’s buttons were 59 px tall, not the 40 px of every other dialog. Such a window and everything in it are kept at 100 %, and the window’s own sheet re-states, at 100 %, the sizes it would otherwise inherit scaled – set as it is polished, so before it is first laid out.

Each preview remembers its own scale, under prefs/preview_scale/<name>.

Classes

PreviewScaleControl

The slider and its percentage: compact, and exempt from its own scale.

PreviewScaler

Scales one preview's subtree, and keeps it scaled as it grows.

Functions

clamp_preview_scale(→ float)

value as a float inside the slider's bounds (1.0 if unreadable).

get_preview_scale(→ float)

The saved scale of the preview called name.

install_preview_scale(→ PreviewScaleControl)

Give panel its own scale slider, saved under name.

refresh_all_preview_scales(→ int)

Rebuild every scaled preview; called after Preferences re-styles.

reset_all_preview_scales(→ int)

Put every live preview back to 100 %, and forget the saved scales.

scale_figure_canvas(→ bool)

Scale a matplotlib canvas's text, dots and lines with its preview.

scale_qss(→ str)

Scale the pixel sizes in a style sheet by factor.

set_preview_scale(→ None)

Remember scale for the preview called name.

Module Contents

class spacr.qt.widgets.preview_scale.PreviewScaleControl(scaler: PreviewScaler, parent=None)[source]

Bases: PySide6.QtWidgets.QWidget

The slider and its percentage: compact, and exempt from its own scale.

Parameters:
  • scaler – the preview’s scaler.

  • parent – owning widget.

Build the slider at the preview’s saved scale.

eventFilter(watched, event)[source]

Double-clicking the percentage goes back to 100 %.

Parameters:
  • watched – the widget the event is for.

  • event – the event; a double-click on the value is consumed.

set_percent(percent: int) → None[source]

Move the slider (and so the preview) to percent.

Parameters:

percent – the scale in percent, 10 to 200.

class spacr.qt.widgets.preview_scale.PreviewScaler(root: PySide6.QtWidgets.QWidget, name: str, scale: float | None = None)[source]

Bases: PySide6.QtCore.QObject

Scales one preview’s subtree, and keeps it scaled as it grows.

Parameters:
  • root – the preview panel.

  • name – the key its scale is saved under.

  • scale – the starting scale; the saved one by default.

Remember the preview and apply its saved scale once it is built.

add_hook(hook: Callable[[float], None]) → None[source]

Call hook(scale) after every change, and once now if scaled.

For what a panel draws itself – a thumbnail size, a figure’s dpi – which no style sheet or size constraint reaches.

Parameters:

hook – called with the new scale; an exception it raises is logged, never passed on.

apply() → None[source]

Put the current scale on every widget of the preview.

eventFilter(watched, event)[source]

Scale what joins the preview later, and sheets set on it later.

Read through getattr: a garbage collection that breaks a cycle through this object clears its attributes while Qt still delivers it events, and a filter that raised then would put an error in the event loop for a preview that is already going away.

Parameters:
  • watched – the widget the event is for.

  • event – the event; never consumed.

refresh() → None[source]

Rebuild after the application sheet changed (Zoom, theme).

scale() → float[source]

The preview’s current scale.

set_scale(scale: float, *, persist: bool = True) → float[source]

Scale the preview to scale now, and remember it.

Parameters:
  • scale – the factor, 1.0 = 100 %.

  • persist – save it for this preview’s next opening.

Returns:

the scale applied, after clamping.

property name: str[source]

The key this preview’s scale is saved under.

spacr.qt.widgets.preview_scale.clamp_preview_scale(value) → float[source]

value as a float inside the slider’s bounds (1.0 if unreadable).

Parameters:

value – anything a stored preference may hold.

spacr.qt.widgets.preview_scale.get_preview_scale(name: str) → float[source]

The saved scale of the preview called name.

Parameters:

name – the preview’s key, e.g. "mask".

spacr.qt.widgets.preview_scale.install_preview_scale(panel: PySide6.QtWidgets.QWidget, name: str, layout=None, *, index: int | None = None, stretch_before: bool = False, prefer_card: bool = True) → PreviewScaleControl[source]

Give panel its own scale slider, saved under name.

Parameters:
  • panel – the preview panel whose contents the slider scales.

  • name – the key its scale is saved under, e.g. "mask".

  • layout – the row to put the slider in when the panel is not in a preview card; None leaves it to the caller.

  • index – where in layout to insert it; the end by default.

  • stretch_before – put a stretch in front of it, for a row whose last item does not already push it right.

  • prefer_card – put it in the enclosing card’s title row, beside Refresh, when there is one (see _PlacesTheControl).

Returns:

the control. Its scaler is control.scaler and on panel.preview_scaler; control.placer.place() places it now.

spacr.qt.widgets.preview_scale.refresh_all_preview_scales() → int[source]

Rebuild every scaled preview; called after Preferences re-styles.

Returns:

how many previews were scaled and so rebuilt.

spacr.qt.widgets.preview_scale.reset_all_preview_scales() → int[source]

Put every live preview back to 100 %, and forget the saved scales.

Returns:

how many live previews were reset.

spacr.qt.widgets.preview_scale.scale_figure_canvas(canvas, scale: float) → bool[source]

Scale a matplotlib canvas’s text, dots and lines with its preview.

A figure draws in points, so its dpi is what makes a 9 pt label take more or fewer pixels. Scaling the dpi the canvas was built with – and keeping the widget’s size – scales everything the figure draws, at the cost of nothing but a redraw. It composes with the GUI scale: spacr.qt.gui_scale.apply_canvas_dpi() draws base dpi x GUI scale x this preview’s scale.

Parameters:
  • canvas – a FigureCanvasQTAgg.

  • scale – the preview’s scale.

Returns:

True if the canvas was rescaled.

spacr.qt.widgets.preview_scale.scale_qss(text: str, factor: float, *, sizes_only: bool = False) → str[source]

Scale the pixel sizes in a style sheet by factor.

Parameters:
  • text – the QSS.

  • factor – the scale; 1.0 returns text unchanged (unless sizes_only).

  • sizes_only – keep only the declarations that were scaled, in rules that had any. That is what a preview’s own sheet is built from: the sizes of every rule it inherits, re-stated at its scale, and nothing about colour – so a theme change needs no rebuild of it.

Returns:

the scaled QSS.

spacr.qt.widgets.preview_scale.set_preview_scale(name: str, scale: float) → None[source]

Remember scale for the preview called name.

Parameters:
  • name – the preview’s key, e.g. "mask".

  • scale – the factor, 1.0 = 100 %; clamped to 10-200 %.