Skip to content

GUI

Qt widgets for building interactive cellier-based applications.

Canvas and dims

cellier.gui.qt.QtCanvasWidget

Wraps a render canvas above a QtDimsControl panel.

Composes the two elements in a QVBoxLayout so that the canvas expands to fill available space while the dims control sits below it at a fixed height. The dims control includes the 2D/3D toggle button (when the scene has 3+ axes), so no separate toggle widget is needed.

Prefer constructing via :meth:from_scene_and_canvas rather than calling __init__ directly.

Parameters:

Name Type Description Default
canvas_view

A CanvasView instance; its .widget property provides the render surface to embed.

required
dims_control QtDimsControl

An already-constructed QtDimsControl instance.

required
parent QWidget | None

Optional Qt parent widget.

None

widget property

widget: QWidget

The outer QWidget to insert into a layout.

dims_control property

dims_control: QtDimsControl

The QtDimsControl panel embedded below the canvas.

from_scene_and_canvas classmethod

from_scene_and_canvas(scene, canvas_view, axis_ranges: dict[int, tuple[int, int]], *, parent: QWidget | None = None) -> QtCanvasWidget

Construct from live scene and canvas objects.

Derives axis labels and the initial dims state from scene so that callers only need to supply axis_ranges (which requires data-store knowledge not available on the dims model itself). The 2D/3D toggle is included automatically when the scene has 3 or more axes: 3D displays the last three axis labels, 2D the last two.

Call controller.connect_widget on the returned widget's dims_control after construction to wire subscriptions.

Parameters:

Name Type Description Default
scene

The live Scene object whose dims this panel controls.

required
canvas_view

The CanvasView whose .widget is the render surface.

required
axis_ranges dict[int, tuple[int, int]]

Mapping of axis index to (min, max), e.g. {0: (0, 99), 1: (0, 511), 2: (0, 511)}.

required
parent QWidget | None

Optional Qt parent widget.

None

close

close() -> None

Unsubscribe the dims control from the bus.

cellier.gui.qt.QtDimsControl

Bidirectional dims slider panel + 2D/3D toggle wired to the cellier v2 bus.

Composes a QWidget container (with a QFormLayout) holding one QLabeledSlider per axis, plus (when axes_2d/axes_3d are given) a toggle button that switches the scene between its 2D and 3D axis sets. Sliders for displayed axes are hidden; only sliced (non-displayed) axes are shown.

Follows the v2 widget pattern:

  • One UUID (self._id) shared by the sliders and the toggle.
  • Subscribed to DimsChangedEvent via controller.connect_widget.
  • Echo-filters its own changes using source_id.
  • Suppresses re-entrant slider signals with blockSignals when applying model-driven updates.
  • The toggle never relabels itself optimistically on click -- it waits for the echoed DimsChangedEvent, same as the sliders, so there is a single source of truth for "what is currently displayed."

Wire to the controller after construction::

control = QtDimsControl(scene_id, axis_ranges=..., axis_labels=...)
controller.connect_widget(control, subscription_specs=control.subscription_specs())

Parameters:

Name Type Description Default
scene_id

UUID of the scene whose slice indices this widget controls.

required
axis_ranges dict[int, tuple[int, int]]

Mapping of axis index to (min, max) for each slider.

required
axis_labels dict[int, str]

Mapping of axis index to display label, e.g. {0: "z", 1: "y", 2: "x"}.

required
initial_slice_indices dict[int, int] | None

Starting slider values; typically scene.dims.selection.slice_indices.

None
initial_displayed_axes tuple[int, ...]

Axes to hide initially; typically scene.dims.selection.displayed_axes.

()
axes_2d tuple[int, ...] | None

Axis indices to display when toggling to 2D, or None to omit the toggle button entirely (e.g. a scene with fewer than 3 axes).

None
axes_3d tuple[int, ...] | None

Axis indices to display when toggling to 3D, or None to omit the toggle button entirely.

None
parent QWidget | None

Optional Qt parent widget for the internal container.

None

widget property

widget: QWidget

The Qt widget to insert into a layout.

Qt seam 1: replace with the backend element for other toolkits.

non_displayed_sliders property writable

non_displayed_sliders: set[int]

Axes excluded from slider display regardless of dims state (e.g. channel axis).

current_index

current_index() -> dict[int, int]

Return the current value of every slider regardless of visibility.

close

close() -> None

Emit closed to trigger bus unsubscription via the controller.

subscription_specs

subscription_specs() -> list[SubscriptionSpec]

Return the inbound subscription this widget requires.

Pass the result to CellierController.connect_widget.

Visual controls

cellier.gui.qt.visuals.QtColormapComboBox

Bidirectional colormap selector wired to the cellier v2 bus.

Wraps a superqt.QColormapComboBox and keeps it in sync with MultiscaleImageAppearance.color_map via AppearanceChangedEvent. Follows the v2 widget pattern: one UUID per widget, source-ID echo filtering, and signal blocking when applying model-driven updates.

Wire to the controller after construction::

combo = QtColormapComboBox(visual_id, initial_colormap="grays")
controller.connect_widget(combo, subscription_specs=combo.subscription_specs())

Parameters:

Name Type Description Default
visual_id UUID

UUID of the visual whose color_map field this widget controls.

required
initial_colormap

Starting colormap — typically visual_model.appearance.color_map.

required
parent

Optional Qt parent widget.

None

widget property

widget

The Qt widget to insert into a layout.

Qt seam 1: replace with the backend element for other toolkits.

close

close() -> None

Emit closed to trigger bus unsubscription via the controller.

add_colormaps

add_colormaps(colormaps: Sequence[Any]) -> None

Add colormaps to the combo box.

Parameters:

Name Type Description Default
colormaps Sequence[Any]

Colormaps to add. Each item can be anything accepted by cmap.Colormap — e.g. a name string, a cmap.Colormap instance, or a color-stop sequence.

required

subscription_specs

subscription_specs() -> list[SubscriptionSpec]

Return the inbound subscription this widget requires.

Pass the result to CellierController.connect_widget.

cellier.gui.qt.visuals.QtClimRangeSlider

Bidirectional contrast-limits slider wired to the cellier v2 bus.

Wraps a superqt.QLabeledDoubleRangeSlider and keeps it in sync with MultiscaleImageAppearance.clim via AppearanceChangedEvent. Follows the v2 widget pattern: one UUID per widget, source-ID echo filtering, and signal blocking when applying model-driven updates.

Wire to the controller after construction::

slider = QtClimRangeSlider(visual_id, clim_range=(0, 255), initial_clim=(0, 200))
controller.connect_widget(slider, subscription_specs=slider.subscription_specs())

Parameters:

Name Type Description Default
visual_id UUID

UUID of the visual whose clim field this widget controls.

required
clim_range tuple[float, float]

(min, max) for the slider range.

required
initial_clim tuple[float, float]

Starting value — typically visual_model.appearance.clim.

required
decimals int

Number of decimal places shown in the slider label. Use 0 for integer dtypes and 2 (or similar) for float data. Default is 2.

2
parent

Optional Qt parent widget.

None

widget property

widget

The Qt widget to insert into a layout.

Qt seam 1: replace with the backend element for other toolkits.

close

close() -> None

Emit closed to trigger bus unsubscription via the controller.

subscription_specs

subscription_specs() -> list[SubscriptionSpec]

Return the inbound subscription this widget requires.

Pass the result to CellierController.connect_widget.

cellier.gui.qt.visuals.QtVolumeRenderControls

Combined render-mode, ISO-threshold, and attenuation widget wired to the cellier v2 bus.

Contains a render-mode QComboBox ("iso" / "smooth_iso" / "mip" / "attenuated_mip") and mode-dependent parameter sliders:

  • ISO threshold slider — visible when mode is "iso" or "smooth_iso".
  • Attenuation slider — visible when mode is "attenuated_mip".

All controls share one UUID so a single on_visual_changed subscription handles all fields. Follows the v2 widget pattern: source-ID echo filtering and signal blocking on model-driven updates.

Wire to the controller after construction::

controls = QtVolumeRenderControls(visual_id, dtype_max=255, ...)
controller.connect_widget(
    controls, subscription_specs=controls.subscription_specs()
)

Parameters:

Name Type Description Default
visual_id UUID

UUID of the visual whose render_mode, iso_threshold, and attenuation fields this widget controls.

required
dtype_max float

Upper bound of the threshold slider — typically the dtype maximum (e.g. 65535 for uint16, 1.0 for float32).

required
initial_render_mode str

Starting render mode — typically visual_model.appearance.render_mode.

required
initial_threshold float

Starting threshold — typically visual_model.appearance.iso_threshold.

required
initial_attenuation float

Starting attenuation coefficient — typically visual_model.appearance.attenuation. Default is 1.0.

1.0
decimals int

Number of decimal places shown in the threshold slider label. Use 0 for integer dtypes and 2 (or similar) for float data. Default is 2.

2
parent

Optional Qt parent widget.

None

widget property

widget

The Qt widget to insert into a layout.

Qt seam 1: replace with the backend element for other toolkits.

close

close() -> None

Emit closed to trigger bus unsubscription via the controller.

subscription_specs

subscription_specs() -> list[SubscriptionSpec]

Return the inbound subscription this widget requires.

Pass the result to CellierController.connect_widget.