Skip to content

redsun.view

Placement

Placement dataclass

Placement()

Where a view asks to be attached.

A placement names no toolkit type, and this module defines no concrete one. Each frontend declares the placements it understands in its own package. A frontend attaches the placements it lists in redsun.Frontend.requires and refuses the rest.

Declaring one is what makes a component a view. A presenter attaches nowhere and declares none.

Keyboard shortcuts

shortcut

shortcut(
    key: str,
    *,
    title: str,
    scope: Scope = "window",
    mac: str | None = None,
    win: str | None = None,
    linux: str | None = None,
    when: Callable[[Any], bool] | None = None,
    repeat: bool = False,
) -> Callable[[F], F]

Return a decorator recording that key runs the method it decorates.

The method is returned unchanged, so it can be a slot too. A session binds the key once the component is built: anywhere in the window, or with scope="view" only while the component's own view has focus.

A presenter's coroutine method runs on the session's loop, and a press while it still runs is ignored. A view's runs only on a frontend whose view_coroutines is true; elsewhere its key is left out.

Parameters:

Name Type Description Default
when Callable[[Any], bool] | None

A function taking the component, such as a method defined above the decorated one. The key acts only while it returns true; the rest of the time the key press goes to the widget that has focus. A frontend asks again each time the focus moves.

None
repeat bool

Whether holding the key runs the method again at the keyboard's repeat rate, as stepping a motor wants. By default a held key runs it once.

False

Raises:

Type Description
ValueError

If the key or the title is empty, the scope is unknown, or when is not a function.

TypeError

When applied to a method that needs arguments besides itself, or to a method that already has a key.

Shortcut dataclass

Shortcut(
    key: str,
    title: str,
    scope: Scope = "window",
    mac: str | None = None,
    win: str | None = None,
    linux: str | None = None,
    when: Callable[[Any], bool] | None = None,
    repeat: bool = False,
)

A key that runs a component's method, as shortcut recorded it.

Raises:

Type Description
ValueError

If the key or the title is empty, the scope is neither "window" nor "view", or the condition is not a function.

key instance-attribute

key: str

The key, in app-model's spelling such as "Ctrl+R"; Ctrl is Command on macOS.

title instance-attribute

title: str

What the key does, as the list of shortcuts shows it.

scope class-attribute instance-attribute

scope: Scope = 'window'

"window" for anywhere in the window, "view" for while the component's view has focus.

mac class-attribute instance-attribute

mac: str | None = None

The key on macOS, when it differs.

win class-attribute instance-attribute

win: str | None = None

The key on Windows, when it differs.

linux class-attribute instance-attribute

linux: str | None = None

The key on Linux, when it differs.

when class-attribute instance-attribute

when: Callable[[Any], bool] | None = None

A function of the component; while it returns false the key does nothing.

repeat class-attribute instance-attribute

repeat: bool = False

Whether a held key runs the method again at the keyboard's repeat rate.

key_here

key_here() -> str

Return the key on the platform this runs on.

Window layout

WindowLayout dataclass

WindowLayout(
    regions: Mapping[str, Node] = dict(),
    sizes: Mapping[str, float] = dict(),
    hidden: Sequence[str] = (),
)

Where views start in a window: what fills each region, how big it is, what starts hidden.

The region names are the frontend's. A view the layout leaves out goes where its own placement asks.

Raises:

Type Description
ValueError

Listing every problem: a view placed twice, or a share outside (0, 1).

regions class-attribute instance-attribute

regions: Mapping[str, Node] = field(default_factory=dict)

What fills each region, by region name.

sizes class-attribute instance-attribute

sizes: Mapping[str, float] = field(default_factory=dict)

The share of the window each region takes, between 0 and 1, by region name.

hidden class-attribute instance-attribute

hidden: Sequence[str] = ()

The views that start hidden.

names property

names: list[str]

The name of every view the layout places, region by region.

fingerprint

fingerprint() -> str

Return a digest that changes whenever the layout does.

Row

Row(*children: Node, sizes: Sequence[float] | None = None)

Bases: Split

Views side by side, left to right.

Each child is a view's name or another node. sizes gives one positive weight per child, and each child takes its weight's share of the width; without it the children share the width equally.

Raises:

Type Description
ValueError

If it holds nothing, or sizes does not give one positive weight per child.

Column

Column(
    *children: Node, sizes: Sequence[float] | None = None
)

Bases: Split

Views stacked, top to bottom.

Each child is a view's name or another node. sizes gives one positive weight per child, and each child takes its weight's share of the height; without it the children share the height equally.

Raises:

Type Description
ValueError

If it holds nothing, or sizes does not give one positive weight per child.

Tabs

Tabs(*names: str, current: str | None = None)

Bases: TabGroup

Views sharing one space as tabs.

Each tab is a view's name. current names the view shown on top; without it the first is.

Raises:

Type Description
ValueError

If it holds nothing, or current is not one of its tabs.

Qt widgets

Qt widgets for interfaces that run plans.

  • ActionButton: a QPushButton carrying a PlanAction, its label following the toggle state.
  • PlanWidget: a frozen dataclass owning one plan's widgets (parameter form, run and pause buttons, action buttons).
  • create_plan_widget: builds a PlanWidget from a PlanSpec and connects the given callbacks.
  • PlanInfoDialog: a dialog rendering a plan's docstring as Markdown.
  • create_param_widget: re-exported from _widget_factory.

ActionButton

ActionButton(
    action: PlanAction, parent: QWidget | None = None
)

Bases: QPushButton

A QPushButton carrying a PlanAction.

Its label follows the toggle state, using the action's toggle_states.

Parameters:

Name Type Description Default
action PlanAction

The button's action.

required
parent QWidget | None

The parent widget.

None

Attributes:

Name Type Description
action PlanAction

The button's action.

release

release() -> None

Show the button released, without emitting toggled.

For an action that ended by itself: unchecking the button any other way reads as the user asking the action to end.

PlanInfoDialog

PlanInfoDialog(
    title: str, text: str, parent: QWidget | None = None
)

Bases: QDialog

Dialog showing information to the user.

Parameters:

Name Type Description Default
title str

The title of the dialog window.

required
text str

Text shown, rendered as Markdown.

required
parent QWidget | None

The parent widget.

None

show_dialog classmethod

show_dialog(
    title: str, text: str, parent: QWidget | None = None
) -> int

Create and show the dialog, and return QDialog.Accepted or QDialog.Rejected.

create_plan_widget

create_plan_widget(
    spec: PlanSpec,
    run_callback: Callable[[], None] | None = None,
    toggle_callback: Callable[[bool], None] | None = None,
    pause_callback: Callable[[bool], None] | None = None,
    action_clicked_callback: Callable[[str], None]
    | None = None,
    action_toggled_callback: Callable[[bool, str], None]
    | None = None,
    plan_callbacks: Sequence[CallbackType] = (),
    extendable: bool = True,
    available_callbacks: Mapping[str, CallbackType]
    | None = None,
    attached_callbacks: Sequence[str] | None = None,
    selection_callback: Callable[[list[str]], None]
    | None = None,
) -> PlanWidget

Build a complete PlanWidget for spec.

Run stays disabled while an input holds an invalid value; see PlanWidget.problems.

Parameters:

Name Type Description Default
spec PlanSpec

The plan's specification.

required
run_callback Callable[[], None] | None

Connected to run_button.clicked for plans that are not continuous.

None
toggle_callback Callable[[bool], None] | None

Connected to run_button.toggled for continuous plans.

None
pause_callback Callable[[bool], None] | None

Connected to pause_button.toggled for pausable plans.

None
action_clicked_callback Callable[[str], None] | None

Called with action_name when an action's button is clicked.

None
action_toggled_callback Callable[[bool, str], None] | None

Called with (checked, action_name) when an action's button is pressed or released.

None
plan_callbacks Sequence[CallbackType]

The document callbacks the plan requires, in the order they run. They are listed first, checked, and cannot be unchecked or moved.

()
extendable bool

Whether the user may attach callbacks after plan_callbacks.

True
available_callbacks Mapping[str, CallbackType] | None

The document callbacks the user may attach, by the name each row is labelled with, in the order offered. Ignored when extendable is False.

None
attached_callbacks Sequence[str] | None

Names the user attached before, in their order. The other available callbacks are listed unchecked after them, and a name not available is ignored. None checks every available callback.

None
selection_callback Callable[[list[str]], None] | None

Called with PlanWidget.attached_callbacks when the user checks, unchecks or moves a callback.

None

create_param_widget

create_param_widget(param: ParamDescription) -> mgw.Widget

Create a magicgui widget for param.

Only the predicates are guarded: a factory raising is a bug and propagates. A parameter no entry of WIDGET_FACTORY_MAP matches gets the widget create_value_widget builds.

PlanWidget dataclass

PlanWidget(
    spec: PlanSpec,
    group_box: QWidget,
    run_button: QPushButton,
    container: Container[ValueWidget[Any]],
    device_widgets: list[ValueWidget[Any]],
    params_widget: QWidget,
    problem_label: QLabel,
    action_buttons: dict[str, ActionButton],
    actions_group: QGroupBox | None = None,
    pause_button: QPushButton | None = None,
    callbacks_list: QListWidget | None = None,
    progress_group: QGroupBox | None = None,
)

The Qt widgets of one plan.

spec instance-attribute

spec: PlanSpec

The plan's specification.

group_box instance-attribute

group_box: QWidget

The top-level page, for a QStackedWidget.

run_button instance-attribute

run_button: QPushButton

The button running or stopping the plan.

container instance-attribute

container: Container[ValueWidget[Any]]

The magicgui Container of parameter widgets.

device_widgets instance-attribute

device_widgets: list[ValueWidget[Any]]

Device parameter widgets (DeviceSequenceEdit or ComboBox), in the Devices group.

params_widget instance-attribute

params_widget: QWidget

Widget holding devices_group and params_group; disabling it locks every parameter input but not the run, stop and pause buttons.

problem_label instance-attribute

problem_label: QLabel

The first of problems, under the parameters; hidden while there is none.

action_buttons instance-attribute

action_buttons: dict[str, ActionButton]

Action buttons by action name.

actions_group class-attribute instance-attribute

actions_group: QGroupBox | None = None

The group box of action buttons, or None if the plan has no actions.

pause_button class-attribute instance-attribute

pause_button: QPushButton | None = None

The pause/resume button, or None if the plan is not pausable.

callbacks_list class-attribute instance-attribute

callbacks_list: QListWidget | None = None

The document callbacks to run the plan with, or None if it runs with none.

The callbacks the plan requires come first, checked and fixed in place; the rest can be checked and dragged into a different order.

progress_group class-attribute instance-attribute

progress_group: QGroupBox | None = None

The "Progress" group of the page, hidden until the plan reports a scope.

problems property

problems: list[str]

Why the plan cannot run, one line per invalid input, prefixed with its parameter.

An input's own problems come first; only an input with none is checked against its parameter's limits. Run stays disabled while the list is not empty.

parameters property

parameters: dict[str, Any]

Current parameter values by name.

The presenter turns them into positional and keyword arguments with collect_arguments / resolve_arguments.

callbacks property

callbacks: list[CallbackType]

The checked document callbacks, in the order the run uses.

attached_callbacks property

attached_callbacks: list[str]

Names of the checked callbacks the user attached, in order.

toggle

toggle(status: bool) -> None

Update the widgets when a continuous plan starts or stops.

The run and pause buttons are set to match status without emitting toggled, so a plan that ended by itself can be shown as stopped.

pause

pause(status: bool) -> None

Update the widgets when a plan pauses or resumes.

The stop button stays enabled, so a paused plan can be stopped.

setEnabled

setEnabled(enabled: bool) -> None

Enable or disable the whole plan widget.

Enabling it enables Run only while problems is empty.

enable_actions

enable_actions(enabled: bool = True) -> None

Enable or disable the actions group box.

get_action_button

get_action_button(action_name: str) -> ActionButton | None

Return the ActionButton for action_name, or None if absent.

has_actions

has_actions() -> bool

Return True if the plan has an action button.

set_values

set_values(values: Mapping[str, Any]) -> None

Show values in the parameter widgets they name.

A name with no widget is skipped. A widget that refuses its value, or a device list naming a device it does not offer, keeps the value it had.

show_progress

show_progress(scopes: Sequence[PlanProgress]) -> None

Show a row for each progress scope of the running plan, in the order given.

A scope is indented under its parent, and a bar is busy while its scope has no known end. An empty scopes hides the group.

Tree view showing and editing device settings from their descriptors.

DescriptorTreeView, a QTreeWidget, shows bluesky describe() / read() dicts as a two-column property tree.

The design follows the ParameterTree widget of pyqtgraph (MIT licence, © 2012 University of North Carolina at Chapel Hill, Luke Campagnola).

DescriptorTreeView

DescriptorTreeView(
    descriptors: dict[str, Descriptor],
    readings: dict[str, Reading[Any]],
    parent: QWidget | None = None,
    *,
    owners: Mapping[str, str] | None = None,
    paths: Mapping[str, DevicePath] | None = None,
)

Bases: QTreeWidget

Two-column property tree for browsing and editing device settings.

Rows are grouped by their name-property key: one header per device name, and under it a header per group a property names with a dash of its own, so cam-properties-Binning is Binning under properties under cam.

Parameters:

Name Type Description Default
descriptors dict[str, Descriptor]

Descriptors by name-property key.

required
readings dict[str, Reading[Any]]

Initial readings for the same keys; only reading["value"] is read.

required
parent QWidget | None

Parent widget.

None
owners Mapping[str, str] | None

Device of each key, for names that hold a dash themselves; a key not listed belongs to what comes before its first dash.

None
paths Mapping[str, DevicePath] | None

Where the signal behind each key, and each device in owners, sit in their tree. A device is then titled by its root and path, and a row by its signal's path below the device's.

None

sig_property_changed class-attribute instance-attribute

sig_property_changed = Signal(str, str, object)

Emitted with the object name, property name and new value of a committed edit.

The edit stays pending until set_value or revert settles it.

set_value

set_value(key: str, value: Any) -> None

Show value for key, the value the device holds.

Settles an edit pending on key, so the row shows what the device read back rather than what was typed. Emits nothing. A key the tree has no row for is ignored.

Parameters:

Name Type Description Default
key str

name-property key.

required

set_enabled

set_enabled(owner: str, enabled: bool) -> None

Enable or disable the editors of every row of owner.

Parameters:

Name Type Description Default
owner str

Device name, the part of a key before its first -.

required

revert

revert(key: str) -> None

Put back the value key had before the edit pending on it.

For an edit the device refused. Emits nothing, and does nothing when no edit is pending on key.

ConfigurationTab

ConfigurationTab(
    configuration: Configuration,
    parent: QWidget | None = None,
)

Bases: DescriptorTreeView

The configuration of a set of devices, shown and edited in a tree.

With no configuration at all, the tree holds one row saying so.

sig_configure class-attribute instance-attribute

sig_configure = Signal(str, object)

Key and value of an edit.

update_value

update_value(key: str, value: object) -> None

Show value, read back from the configuration signal key.

set_locked

set_locked(names: frozenset[str]) -> None

Disable the rows in names, and below the devices in it, and enable the rest.

A row with no path is disabled when its owner is in names.

Icons from the Material Design icon font, as the built-in views draw them.

An icon is named as Material Design Icons 7 names it, without a prefix: play, content-save, crosshairs-gps. It takes its colours from the palette of the widget it is on, and is drawn again when that palette changes, so it stays readable through a switch between light and dark.

set_icon

set_icon(
    button: QAbstractButton, name: str, words: str
) -> None

Show the icon name on button in place of text, with words as tooltip and accessible name.

The icon follows the button's palette from then on. Calling this again on the same button changes its icon.

Parameters:

Name Type Description Default
name str

The icon's name in Material Design Icons 7, without a prefix, such as play.

required
words str

What the button does, in a few words: a screen reader reads them, and they are the tooltip.

required

set_item_icon

set_item_icon(
    combo: QComboBox, index: int, name: str
) -> None

Show the icon name beside item index of combo, following its palette.

name is the icon's name in Material Design Icons 7, without a prefix.

collapsible_section

collapsible_section(
    title: str, parent: QWidget
) -> QCollapsible

Return a collapsible section of parent titled title, its arrows icons following its palette.

The arrows are given when the section is made. Left to itself, superqt draws its default arrows on a picture sized by the font's point size, which a font sized in pixels does not have, and Qt's painter complains about the empty picture.

set_collapsible_icons

set_collapsible_icons(collapsible: QCollapsible) -> None

Show collapsible's arrows as icons following its palette.

QCollapsible draws its own arrows once, in the text colour of that moment, so a light/dark switch would leave them in the old colour.

Built-ins

LogView

LogView(name: str, parent: QWidget)

Bases: QWidget

Read-only console of the running session's log records.

Records logged before the view existed are shown too, read from the session buffer. The level selector sets the lowest level shown; since the view redraws from the buffer, lowering the level again brings records back.

Application and service records have their own tabs. The Services tab appears once a service logs, and its selector narrows it to one service. Clear log window and Save logs... act on the tab and service shown.

Records are coloured by level, with one palette for light and one for dark backgrounds, chosen from the view's background and redrawn when the palette changes.

New records are drawn in batches, so a burst does not stall the window, and each console keeps no more lines than the buffer holds for it.

With session log files open, Save logs... copies the files of the tab shown and Open log folder opens their folder in the file browser; without them the folder button is disabled.

placement class-attribute instance-attribute

placement: Placement = Dock('bottom')

Docked at the bottom of the main window.

level property

level: int

The lowest level currently displayed.

service property

service: str | None

The service the Services tab shows, None for every service.

colors property

colors: dict[int, str]

The level colours in use, chosen from the console's background.

changeEvent

changeEvent(event: QEvent | None) -> None

Redraw in the colours of the palette just applied.

closeEvent

closeEvent(event: QCloseEvent | None) -> None

Stop following the buffer once the console is closed.

set_level

set_level(level: int) -> None

Show only records at or above level, redrawing from the buffer.

clear

clear() -> None

Empty the console of the tab shown.

The buffer is untouched, so Save logs... still writes everything and changing the level brings records back.

save

save(path: str) -> None

Write the records of the tab shown to path, whatever the displayed level.

The Application tab writes application records; the Services tab the selected service's, or every service's in turn. They come from the session's log files if open, so records the buffer dropped are included, and from the buffer otherwise.

LogWindowAction

LogWindowAction(name: str, parent: QWidget)

Bases: QAction

The Logs entry of the View menu, showing the session's log in a window.

The window is a LogView, made when the entry is chosen and deleted when it is closed. Choosing the entry while the window is open brings it to the front.

placement class-attribute instance-attribute

placement: Placement = MenuItem('View')

An entry in the View menu.

show_logs

show_logs() -> None

Open the log window, or bring the open one to the front.

AcquisitionView

AcquisitionView(name: str, parent: QWidget)

Bases: QWidget, Loggable

Choose a plan, fill its parameters, and run, pause and stop it.

One PlanWidget per plan the presenter describes, chosen from a list, and the directory runs write under. The view shows a plan running only once the presenter reports it started, and shows that a plan was stopped, or why it failed, until it runs again. The plan chosen last is kept in the session's settings. Ctrl+R runs the chosen plan and Ctrl+. stops the running one, anywhere in the window.

placement class-attribute instance-attribute

placement: Placement = Dock('left')

Where the view sits in the main window.

sig_launch class-attribute instance-attribute

sig_launch = Signal(str, dict, tuple)

Plan, its parameter values, and the names of the callbacks attached.

sig_pause class-attribute instance-attribute

sig_pause = Signal()

The user paused the running plan.

sig_resume class-attribute instance-attribute

sig_resume = Signal()

The user resumed the paused plan.

sig_stop class-attribute instance-attribute

sig_stop = Signal()

The user stopped the plan.

sig_action class-attribute instance-attribute

sig_action = Signal(str, bool)

Action, and whether its button is pressed.

sig_base_dir class-attribute instance-attribute

sig_base_dir = Signal(object)

The directory the user chose for runs to write under.

sig_label class-attribute instance-attribute

sig_label = Signal(str)

The label the user typed for the file names of later runs.

setup

setup(
    acquisition: DescribesPlans, settings: Settings
) -> None

Build one widget per plan acquisition describes, and read settings.

set_started

set_started(
    plan: str, values: dict[str, Any] | None = None
) -> None

Show plan running, and lock the chooser, the root and the label until it ends.

The plan's form shows the values it was launched with.

set_done

set_done(plan: str) -> None

Show plan ended, and free the chooser, the root and the label.

set_stopped

set_stopped(plan: str) -> None

Show plan stopped, until it runs again.

set_failed

set_failed(plan: str, message: str) -> None

Show plan ended because of message, until it runs again.

update_progress

update_progress(scopes: tuple[PlanProgress, ...]) -> None

Show the progress of the running plan.

update_action

update_action(action: str, state: object) -> None

Set the running plan's button for action to state.

update_base_dir

update_base_dir(path: Path) -> None

Show the directory runs write under.

run_plan

run_plan() -> None

Run the chosen plan as its Run button does, unless a plan runs.

stop_plan

stop_plan() -> None

Ask to stop the running plan, or the one launched and not yet started.

LightView

LightView(
    name: str,
    parent: QWidget,
    *,
    write_while_dragging: bool = False,
)

Bases: QWidget, Loggable

Switch lights on and off and set their intensity: a group per light.

The Lights tab holds one LightGroup per light. The Configuration tab shows and edits every light's configuration. The Advanced tab chooses whether the intensity is also written while the slider is dragged; the choice is kept in the session's settings, under a key named after this view, and wins over the keyword.

Parameters:

Name Type Description Default
write_while_dragging bool

Write the intensity during a drag as well, at most every 100 ms, until the Advanced tab says otherwise.

False

placement class-attribute instance-attribute

placement: Placement = Dock('right')

Where the view sits in the main window.

group_class class-attribute

group_class: MakesLightGroup = LightGroup

Widget built for each light; a subclass may name a subclass of its own that takes the same arguments.

sig_enabled class-attribute instance-attribute

sig_enabled = Signal(str, bool)

Device, and the state asked for.

sig_intensity class-attribute instance-attribute

sig_intensity = Signal(str, float)

Device, and the intensity asked for.

sig_configure class-attribute instance-attribute

sig_configure = Signal(str, object)

Key and value of an edit in the Configuration tab.

tabs property

tabs: QTabWidget

The Lights, Configuration and Advanced tabs, to which a subclass may add.

setup

setup(lights: DescribesLights, settings: Settings) -> None

Build a group per light lights describes, and read settings.

update_enabled

update_enabled(device: str, on: bool) -> None

Show whether device is on.

update_intensity

update_intensity(device: str, value: float) -> None

Show the intensity device reads back.

set_failed

set_failed(device: str, message: str) -> None

Show that the last write to device failed with message.

update_configuration

update_configuration(key: str, value: object) -> None

Show value, read back from the configuration signal key.

set_locked

set_locked(names: frozenset[str]) -> None

Disable the lights in names, and below the devices in it, and enable the rest.

LightGroup

LightGroup(
    device: str,
    info: LightInfo,
    *,
    write_while_dragging: bool,
    parent: QWidget | None = None,
)

Bases: QGroupBox

A light's on/off button and, when it has one, its intensity.

The controls show what the light reads back. The intensity is written when the slider is let go or stepped, when the field is changed (on Enter, on leaving it, or with its arrows), and, with write_while_dragging, during a drag at most every 100 ms.

sig_enabled class-attribute instance-attribute

sig_enabled = Signal(str, bool)

Device, and the state asked for.

sig_intensity class-attribute instance-attribute

sig_intensity = Signal(str, float)

Device, and the intensity asked for.

set_enabled

set_enabled(on: bool) -> None

Show whether the light is on, as read back, in the button's icon and tooltip as well.

set_intensity

set_intensity(value: float) -> None

Show the intensity read back, unless the user is dragging or typing.

set_failed

set_failed(message: str) -> None

Show why the last write failed.

set_locked

set_locked(locked: bool) -> None

Disable the controls while locked; readbacks keep updating.

set_write_while_dragging

set_write_while_dragging(on: bool) -> None

Write the intensity during a drag as well, at most every 100 ms.

PositionerView

PositionerView(
    name: str,
    parent: QWidget,
    *,
    repeat_delay: int = 400,
    repeat_interval: int = 50,
    steps: Sequence[float] = DEFAULT_STEPS,
    step_box: StepBox = "combobox",
    undo_delay: int = 5000,
)

Bases: QWidget, Loggable

Move devices by hand: a row per axis, grouped by device.

The Motors tab holds one PositionerGroup per device the positioner describes, and the saved positions. The Configuration tab shows and edits the configuration of every axis. The Advanced tab sets the repeat interval of held step buttons. With an axis row or its step button focused, Left and Right step that axis down and up; they are keyboard shortcuts, so the session file and the Keyboard shortcuts list show and change them. The session's settings keep the saved positions and the repeat interval, under keys named after this view.

Parameters:

Name Type Description Default
repeat_delay int

Milliseconds a step button is held before its step repeats.

400
repeat_interval int

Milliseconds between two repeated steps, until one is set in the Advanced tab; kept between 10 and 300.

50
steps Sequence[float]

Step sizes offered in each axis' step box.

DEFAULT_STEPS
step_box StepBox

"combobox" lists the sizes in steps; "spinbox" takes any size from the smallest to the largest of them, starting from the default one, and its arrows move it by decades.

'combobox'
undo_delay int

Milliseconds Undo is offered after a saved position is removed.

5000

placement class-attribute instance-attribute

placement: Placement = Dock('right')

Where the view sits in the main window.

group_class class-attribute

group_class: MakesPositionerGroup = PositionerGroup

Widget built for each device; a subclass may name a subclass of its own that takes the same arguments.

sig_move class-attribute instance-attribute

sig_move = Signal(str, str, float)

Device, axis and step, when a step button is pressed or repeats, or Left or Right steps the focused axis.

sig_move_to class-attribute instance-attribute

sig_move_to = Signal(str, dict)

Device and the positions to go to, by axis.

sig_stop_device class-attribute instance-attribute

sig_stop_device = Signal(str)

Device, when its Stop button is clicked.

sig_configure class-attribute instance-attribute

sig_configure = Signal(str, object)

Key and value of an edit in the Configuration tab.

tabs property

tabs: QTabWidget

The Motors, Configuration and Advanced tabs, to which a subclass may add.

setup

setup(
    positioner: DescribesAxes, settings: Settings
) -> None

Build a group per device positioner describes, and read settings.

update_readback

update_readback(
    device: str, axis: str, value: float
) -> None

Show value as the readback of axis of device.

update_limits

update_limits(
    device: str,
    axis: str,
    low: float | None,
    high: float | None,
) -> None

Take targets for axis of device from low to high only.

set_moving

set_moving(device: str, moving: bool) -> None

Show whether device moves.

set_failed

set_failed(device: str, message: str) -> None

Show that the last move of device failed with message.

update_configuration

update_configuration(key: str, value: object) -> None

Show value, read back from the configuration signal key.

set_locked

set_locked(names: frozenset[str]) -> None

Disable the axes in names, and below the devices in it, and enable the rest.

step_down

step_down() -> None

Step the axis whose row has focus down by its step size.

step_up

step_up() -> None

Step the axis whose row has focus up by its step size.

PositionerGroup

PositionerGroup(
    device: str,
    axes: Mapping[str, AxisInfo],
    *,
    steps: Sequence[float],
    repeat_delay: int,
    repeat_interval: int,
    step_box: StepBox = "combobox",
    parent: QWidget | None = None,
)

Bases: QGroupBox

A device's axes, its state, and buttons to stop it and save where it is.

Parameters:

Name Type Description Default
steps Sequence[float]

Step sizes offered in each axis' step box; a typed size is accepted.

required
repeat_delay int

Milliseconds a step button is held before its step repeats.

required
repeat_interval int

Milliseconds between two repeated steps.

required
step_box StepBox

"combobox" lists the sizes in steps; "spinbox" takes any size from the smallest to the largest of them, starting from the default one, and its arrows move it by decades.

'combobox'

Raises:

Type Description
ValueError

If steps is empty, or step_box is neither choice.

sig_move class-attribute instance-attribute

sig_move = Signal(str, str, float)

Device, axis and step, when a step is asked.

sig_move_to class-attribute instance-attribute

sig_move_to = Signal(str, dict)

Device and the positions to go to, by axis.

sig_save class-attribute instance-attribute

sig_save = Signal(str)

Device, when its position is to be saved.

sig_stop class-attribute instance-attribute

sig_stop = Signal(str)

Device, when it is to stop.

positions property

positions: dict[str, float]

The last readback of each axis.

focused_axis

focused_axis() -> str | None

Return the axis whose row or step button has focus, or None.

step

step(axis: str, sign: float) -> None

Step axis by its chosen size times sign, unless the device is locked.

set_readback

set_readback(axis: str, value: float) -> None

Show value as the readback of axis.

set_limits

set_limits(
    axis: str, low: float | None, high: float | None
) -> None

Take targets for axis from low to high only; None for no bound.

set_moving

set_moving(moving: bool) -> None

Show that the device moves; a failure stays shown until the next move.

show_message

show_message(message: str) -> None

Show message in the state line until the next move.

set_failed

set_failed(message: str) -> None

Show that the last move failed, and why.

set_locked

set_locked(locked: bool) -> None

Disable the controls while locked; readbacks keep updating.

A control holding the focus gives it to its row, or to the first row for a button above the rows, so the focus stays with the locked device.

set_axes_locked

set_axes_locked(axes: Set[str]) -> None

Disable the rows of axes, and the stop and save buttons while any is held.

Readbacks keep updating, and the focus moves as in set_locked.

set_repeat_interval

set_repeat_interval(milliseconds: int) -> None

Repeat every step button at milliseconds while held.

AcquisitionStack

The acquisition presenter with its view.

PositionerStack

The positioner presenter with its view.

LightStack

The light presenter with its view.