erlab.interactive.utils

Various helper functions and extensions to Qt and pyqtgraph.

This module contains various helper functions and classes that extend the functionality of pyqtgraph and Qt.

Functions

copy_to_clipboard(content)

Copy content to the clipboard.

file_loaders([file_name])

Generate a dictionary of namefilters and loader functions for file dialogs.

format_1d_numeric_array_code(values)

Format one-dimensional numeric values as compact executable Python code.

format_call_kwargs(d)

Format mapping arguments for a call site.

format_kwargs(d)

Format a dictionary of keyword arguments for a function call.

generate_code(func, args, kwargs[, module, ...])

Generate Python code for a function call.

load_fit_ui(*[, parent])

Load a fit result from a file.

load_ui(uifile[, baseinstance])

Load a Qt Designer .ui file with stable behavior under coverage tracing.

make_crosshairs([n])

Create a pyqtgraph.TargetItem and associated RotatableLines.

parse_data(data)

qt_is_valid(*objects)

Return True only if every object is a valid Qt object.

save_fit_ui(fit_result, *[, parent])

Save a fit result to a file using a file dialog.

single_shot(receiver, msec, callback, *guards)

Invoke a delayed callback without crashing if the receiver is deleted.

wait_dialog(parent, message)

Show a wait dialog while executing a block of code.

Classes

AnalysisWidgetBase([orientation, num_ax, ...])

AnalysisWidgetBase.

AnalysisWindow(data[, title, layout, ...])

BetterAxisItem(*args, **kwargs)

BetterSpinBox(*args[, integer, compact, ...])

An improved spinbox.

DictMenuBar([parent])

ExclusiveComboGroup([parent, exclude_first])

A group of mutually exclusive comboboxes.

IconActionButton(action[, on, off, ...])

IconButton that supports linking to a QAction.

IconButton([on, off, on_fallback, ...])

Convenience class for creating a QPushButton with a qtawesome icon (or a QIcon).

IdentifierValidator

Validator for Python identifiers.

KeyboardEventFilter

Event filter that intercepts select all and copy shortcuts.

MessageDialog([parent, title, text, ...])

A QDialog that mimics some syntax and look of a QMessageBox.

ParameterGroup([widgets, ncols, groupbox_kw])

Easy creation of groupboxes with multiple varying parameters.

PythonHighlighter([document, style])

Syntax highlighter for Python code using Pygments.

ResizingLineEdit(*args, **kwargs)

QLineEdit that resizes itself to fit the text.

RotatableLine([offset, target])

pyqtgraph.InfiniteLine that rotates under drag.

SingleLinePlainTextEdit([parent])

A QPlainTextEdit constrained to a single line (LineEdit-like).

ToolImageOutputDefinition(data_method[, ...])

Definition for a manager-tracked ImageTool output exposed by a ToolWindow.

ToolScriptProvenanceDefinition(start_label)

Declarative script-style provenance for a ToolWindow action or output.

ToolWindow(*args, **kwargs)

A window that can be saved and restored from a netcdf file.

xImageItem([image])

pyqtgraph.ImageItem with additional functionality.

class erlab.interactive.utils.AnalysisWidgetBase(orientation='vertical', num_ax=2, link='both', cut_to_data='none', **kwargs)[source]

Bases: GraphicsLayoutWidget

AnalysisWidgetBase.

Parameters:
  • orientation (Literal['vertical', 'horizontal'], default: "vertical") – Sets the orientation of the plots, by default “vertical”

  • num_ax (int, default: 2) – Sets the number of axes.

  • link (Literal['x', 'y', 'both', 'none'], default: "both") – Link axes, by default “both”

  • cut_to_data (Literal['in', 'out', 'both', 'none'], default: "none") – Whether to remove outliers by adjusting color levels, by default “none”

initialize_layout(nax)[source]
get_axis_pos(ax)[source]
get_hist_pos(ax)[source]
setStretchFactors(factors)[source]
setStretchFactor(i, factor)[source]
set_input(data=None)[source]
add_roi(i)[source]
class erlab.interactive.utils.AnalysisWindow(data, title=None, layout='horizontal', data_is_input=True, analysisWidget=None, *args, **kwargs)[source]

Bases: ToolWindow

addParameterGroup(*args, **kwargs)[source]
closeEvent(event)[source]
class erlab.interactive.utils.BetterAxisItem(*args, **kwargs)[source]

Bases: AxisItem

updateAutoSIPrefix()[source]
tickStrings(values, scale, spacing)[source]
labelString()[source]
setLabel(text=None, units=None, unitPrefix=None, **args)[source]
class erlab.interactive.utils.BetterSpinBox(*args, integer=False, compact=True, discrete=False, decimals=3, significant=False, scientific=False, exact_float=False, value=0.0, prefix='', trim='k', **kwargs)[source]

Bases: QAbstractSpinBox

An improved spinbox.

Signals:
  • valueChanged – Emitted when the value is changed.

  • textChanged – Emitted when the text is changed.

Parameters:
  • integer (bool, default: False) – If True, the spinbox will only display integer values.

  • compact (bool, default: True) – Whether to reduce the height of the spinbox.

  • discrete (bool, default: False) –

    If True the spinbox will only step to pre-determined discrete values.

    If False, the spinbox will just add or subtract the predetermined increment when increasing or decreasing the step.

  • decimals (int, default: 3) – The precision of the spinbox. See the significant argument for the meaning. When integer is True, this argument is ignored.

  • significant (bool, default: False) –

    If True, decimals will specify the total number of significant digits, before or after the decimal point, ignoring leading zeros.

    If False, decimals will specify the total number of digits after the decimal point, including leading zeros.

    When integer or scientific is True, this argument is ignored.

  • scientific (bool, default: False) – Whether to print in scientific notation.

  • exact_float (bool, default: False) – If True, floating-point text entered by the user is kept as the accepted display text and parsed directly with float instead of being reformatted to decimals on commit. Programmatic value changes use the shortest round-tripping float representation.

  • value (float, default: 0.0) – Initial value of the spinbox.

setPrefix(prefix)[source]
prefix()[source]
setDecimals(decimals)[source]
decimals()[source]
setRange(mn, mx)[source]
widthFromText(text)[source]
widthFromValue(value)[source]
setMaximum(mx)[source]
setMinimum(mn)[source]
setSingleStep(step)[source]
singleStep()[source]
maximum()[source]
minimum()[source]
value()[source]
text()[source]
textFromValue(value)[source]
valueFromText(text)[source]
stepBy(steps)[source]
stepEnabled()[source]
setValue(val)[source]
fixup(_)[source]
validate(strn, pos)[source]
editingFinishedEvent()[source]
keyPressEvent(evt)[source]
focusInEvent(evt)[source]
class erlab.interactive.utils.DictMenuBar(parent=None, **kwargs)[source]

Bases: QMenuBar

add_items(**kwargs)[source]
parse_menu(parent, **kwargs)[source]
parse_action(actopts)[source]
class erlab.interactive.utils.ExclusiveComboGroup(parent=None, exclude_first=False)[source]

Bases: QObject

A group of mutually exclusive comboboxes.

Adapted from https://stackoverflow.com/a/66093311.

This group stores only weak references to the comboboxes, so it is necessary to keep a reference to the comboboxes elsewhere in the code.

addCombo(combo)[source]
class erlab.interactive.utils.IconActionButton(action, on=None, off=None, text_from_action=False, *, on_fallback=None, off_fallback=None, **kwargs)[source]

Bases: IconButton

IconButton that supports linking to a QAction.

Parameters:
  • action (QAction) – The QAction to be associated with this button.

  • on (str or QIcon, optional) – The icon to display when the button is in the “on” state.

  • off (str or QIcon, optional) – The icon to display when the button is in the “off” state. If action is not toggleable, this icon will never be displayed.

  • text_from_action (bool, optional) – If True, the button’s text will be set from the QAction’s text. Otherwise, the text will be left empty.

  • on_fallback (str or QIcon, optional) – Fallback icon for the “on” state if on is a null QIcon.

  • off_fallback (str or QIcon, optional) – Fallback icon for the “off” state if off is a null QIcon.

  • **kwargs – Additional keyword arguments passed to the IconButton constructor.

setAction(action)[source]

Associate a QAction with this button.

refresh_icons()[source]
class erlab.interactive.utils.IconButton(on=None, off=None, *, on_fallback=None, off_fallback=None, icon_kw=None, **kwargs)[source]

Bases: QPushButton

Convenience class for creating a QPushButton with a qtawesome icon (or a QIcon).

This button adapts to dark mode changes by resetting the qtawesome cache when a color palette change is detected.

Parameters:
  • on (str or QIcon, optional) – The icon to display when the button is in the “on” state. If off is not provided, this will be the only icon displayed.

  • off (str or QIcon, optional) – The icon to display when the button is in the “off” state. If provided, the button will be checkable, and the icon will change when the button is toggled.

  • on_fallback (str or QIcon, optional) – Fallback icon for the “on” state if on is a null QIcon.

  • off_fallback (str or QIcon, optional) – Fallback icon for the “off” state if off is a null QIcon.

  • icon_kw (dict, optional) – Additional keyword arguments to pass to qtawesome.icon(). This can be used to customize the icon’s appearance, such as size or color.

  • **kwargs – Additional keyword arguments passed to the QPushButton constructor.

setChecked(value)[source]
get_icon(icon)[source]
refresh_icons()[source]
changeEvent(evt)[source]
class erlab.interactive.utils.IdentifierValidator[source]

Bases: QValidator

Validator for Python identifiers.

This validator checks if the input string is a valid Python identifier, and provides a fixup method to convert invalid identifiers into valid ones. Use with QLineEdit to restrict user input to valid Python identifiers.

validate(input_str, pos)[source]
fixup(input_str)[source]
class erlab.interactive.utils.KeyboardEventFilter[source]

Bases: QObject

Event filter that intercepts select all and copy shortcuts.

For some operating systems, shortcuts are often intercepted by actions in the menu bar. This filter ensures that the shortcuts work as expected when the target widget has focus.

This filter can be used when the target widget does receive the shortcut event with type QtCore.QEvent.Type.ShortcutOverride, but does not respond to it. If the target widget never receives the event, a different approach using the current focus widget is needed.

eventFilter(obj=None, event=None)[source]
class erlab.interactive.utils.MessageDialog(parent=None, title='', text='', informative_text='', detailed_text='', buttons=None, default_button=None, icon_pixmap=None)[source]

Bases: QDialog

A QDialog that mimics some syntax and look of a QMessageBox.

The difference is that this supports rich detailed text, whereas QMessageBox only supports plain text for detailed text. Mainly used for showing tracebacks.

As such, the critical() static method is implemented, which mimics the API of critical.

setDetailedText(text)[source]
detailedText()[source]
setInformativeText(text)[source]
informativeText()[source]
setText(text)[source]
text()[source]
static critical(parent, title, text, informative_text='', detailed_text=None, buttons=None)[source]

Show a critical message dialog.

Works like critical when showing an error message, but automatically adds the traceback to the informative text if called from within an exception handler (i.e., sys.exception() does not return None).

Parameters:
  • parent (QWidget | None) – Parent widget.

  • title (str) – Title of the dialog.

  • text (str) – Main text of the dialog.

  • informative_text (str, default: "") – Additional informative text.

  • detailed_text (str | None, default: None) – Detailed text to show when expanding the details. If None, the current exception traceback will be used. If no exception is being handled, the detailed text will be empty. If you want to provide custom detailed text, pass a string.

  • buttons (StandardButton | None, default: None) – Buttons to show. If None, only an “OK” button is shown.

Returns:

int – Result of the dialog (e.g., QDialog.Accepted or QDialog.Rejected).

Return type:

int

class erlab.interactive.utils.ParameterGroup(widgets=None, ncols=1, groupbox_kw=None, **widgets_kwargs)[source]

Bases: QGroupBox

Easy creation of groupboxes with multiple varying parameters.

Can be used in many different interactive tools for dynamic data analysis.

Parameters:
  • ncols (int, default: 1) – Number of columns in the layout.

  • groupbox_kw (dict | None, default: None) – Keyword arguments passed onto PySide6.QtWidgets.QGroupBox.

  • params – See Examples.

Signals:

sigParameterChanged(dict)

Examples

>>> ParameterGroup(
    **{
        "a": QtWidgets.QDoubleSpinBox(range=(0, 1), singleStep=0.01, value=0.2),
        "b": dict(qwtype="dblspin", range=(0, 2), singleStep=0.04),
        "c": QtWidgets.QSlider(range=(0, 10000))
    }
)
VALID_QWTYPE: Mapping[str, type[QWidget]] = mappingproxy({'spin': <class 'PyQt6.QtWidgets.QSpinBox'>, 'dblspin': <class 'PyQt6.QtWidgets.QDoubleSpinBox'>, 'btspin': <class 'erlab.interactive.utils.BetterSpinBox'>, 'slider': <class 'PyQt6.QtWidgets.QSlider'>, 'chkbox': <class 'PyQt6.QtWidgets.QCheckBox'>, 'pushbtn': <class 'PyQt6.QtWidgets.QPushButton'>, 'chkpushbtn': <class 'PyQt6.QtWidgets.QPushButton'>, 'combobox': <class 'PyQt6.QtWidgets.QComboBox'>, 'fitparam': <class 'erlab.interactive.utils.FittingParameterWidget'>})
layout()[source]
static getParameterWidget(qwtype=None, **kwargs)[source]

Initialize the PySide6.QtWidgets.QWidget corresponding to qwtype.

Parameters:

qwtype (Literal['spin', 'dblspin', 'btspin', 'slider', 'chkbox', 'pushbtn', 'chkpushbtn', 'combobox', 'fitparam'] | None, default: None) – Type of the widget, must a key of ParameterGroup.VALID_QWTYPE.

set_values(**kwargs)[source]
widget_value(widget)[source]
widget_change_signal(widget)[source]
global_connect()[source]
widgets_of_type(widgetclass)[source]
property values: dict[str, float | int | bool]
class erlab.interactive.utils.PythonHighlighter(document=None, *, style=None)[source]

Bases: QSyntaxHighlighter

Syntax highlighter for Python code using Pygments.

setDocument(doc)[source]
highlightBlock(text)[source]
class erlab.interactive.utils.ResizingLineEdit(*args, **kwargs)[source]

Bases: QLineEdit

QLineEdit that resizes itself to fit the text.

This line edit automatically adjusts its size to fit the content as the user types. Adopted from https://stackoverflow.com/a/73663065.

class erlab.interactive.utils.RotatableLine(offset=0.0, target=None, **kwargs)[source]

Bases: InfiniteLine

pyqtgraph.InfiniteLine that rotates under drag.

The position can be changed by providing a pyqtgraph.TargetItem which will drag the line along with it.

Using the constructor function make_crosshairs() is recommended for creating several lines at once.

Parameters:
  • offset (float, default: 0.0) – Offset angle in degrees.

  • target (TargetItem | None, default: None) – Target item to link the position of the line to.

  • **kwargs – Additional keyword arguments to pass to pyqtgraph.InfiniteLine.

Signals:

sigAngleChanged(float) – Emitted when the angle of the line is changed.

property angle_effective: float

The angle of the line relative to the initial angle.

Link with another RotatableLine.

Providing another RotatableLine will link the angles of both lines.

setAngle(angle)[source]
set_target(target)[source]
mouseDragEvent(ev)[source]
class erlab.interactive.utils.SingleLinePlainTextEdit(parent=None)[source]

Bases: QPlainTextEdit

A QPlainTextEdit constrained to a single line (LineEdit-like).

This mainly exists to allow for syntax highlighting in a single-line text input.

keyPressEvent(e)[source]
insertFromMimeData(source)[source]
setText(text)[source]

Set the text of the widget, replacing newlines with spaces.

text()[source]

Get the text of the widget.

class erlab.interactive.utils.ToolImageOutputDefinition(data_method, provenance=None)[source]

Bases: object

Definition for a manager-tracked ImageTool output exposed by a ToolWindow.

data_method: str
provenance: ToolScriptProvenanceDefinition | None = None
class erlab.interactive.utils.ToolScriptProvenanceDefinition(start_label, label=None, label_method=None, expression_method=None, operations_method=None, assign=None, assign_method=None, prelude=None, prelude_method=None, active_name=None, active_name_method=None, seed_code=None, seed_code_method=None)[source]

Bases: object

Declarative script-style provenance for a ToolWindow action or output.

start_label: str
label: str | None = None
label_method: str | None = None
expression_method: str | None = None
operations_method: str | None = None
assign: str | tuple[str, ...] | None = None
assign_method: str | None = None
prelude: str | None = None
prelude_method: str | None = None
active_name: str | None = None
active_name_method: str | None = None
seed_code: str | None = None
seed_code_method: str | None = None
class erlab.interactive.utils.ToolWindow(*args, **kwargs)[source]

Bases: QMainWindow, Generic[M]

A window that can be saved and restored from a netcdf file.

Mainly for interactive tools used in the ImageTool manager.

For the saving and restoring to work, subclasses must follow some rules:

  • Subclasses must have single positional argument data in their constructor, which is an xarray.DataArray containing the main data to be analyzed. Additional arguments can be added as needed.

  • Subclasses must implement a pydantic model which contains all the information needed to restore the state of the tool. The model should be assigned to the class attribute StateModel.

  • The property tool_status must be implemented so that its getter returns an instance of StateModel by gathering the current state of child widgets, and its setter applies a given instance of StateModel to set the state of child widgets.

  • The property tool_data must be implemented to return the main xarray.DataArray being analyzed, which will be passed to the constructor of the subclass when restoring from a file.

For tools that support refreshing their data from an ImageTool source, subclasses should also override the following hooks:

  • update_data must apply replacement data to the existing window without recreating it. Return False when the incoming data is recognized but cannot be applied yet, so the tool remains marked as stale.

  • validate_update_data can normalize or reject incoming source data before update_data runs. Raise an exception to mark the source as unavailable.

  • _cancel_background_work can stop worker threads or other asynchronous work before update_data mutates the tool state. Override BACKGROUND_TASK_TIMEOUT_MS as needed to change the default wait timeout.

For full compatibility with the ImageTool manager, the following optional attributes, properties, or hooks can also be set:

  • The class attribute tool_name should be set to a short string identifying the tool. For example, "dtool", "ktool", etc.

  • The class attribute IMAGE_TOOL_OUTPUTS can be populated with named manager-tracked outputs that should open as refreshable child ImageTools. Each output id maps to a ToolImageOutputDefinition.

  • The property preview_imageitem can be implemented to return a pyqtgraph.ImageItem which will be used to generate a preview image in the ImageTool manager.

  • The property info_text can be implemented to return a HTML string that describes the current state of the tool, which will be shown in the ImageTool manager.

  • If you implement preview_imageitem or info_text, you should emit the signal sigInfoChanged without any arguments whenever the content of these properties changes. This will ensure that the ImageTool manager updates its display.

  • Emit sigDataChanged whenever the displayed tool data or any manager-visible ImageTool outputs have changed. Managed descendants use this to become stale or auto-refresh from the current tool state.

tool_name: str = 'tool'
BACKGROUND_TASK_TIMEOUT_MS: ClassVar[int] = 5000
COPY_PROVENANCE: ClassVar[ToolScriptProvenanceDefinition | None] = None
IMAGE_TOOL_OUTPUTS: ClassVar[Mapping[str | Enum, ToolImageOutputDefinition]] = {}
StateModel: type[TypeVar(M, bound= pydantic.BaseModel)]
centralWidget()[source]

Return the content widget shown below the source-status banner.

setCentralWidget(widget)[source]

Set the main content widget while preserving the source-status banner.

current_provenance_spec()[source]

Return replay provenance for the main copy-code action.

Set COPY_PROVENANCE for the common declarative script-based case. Override this method only when the tool needs custom behavior beyond ToolScriptProvenanceDefinition. This describes the main tool action, not any manager-tracked child ImageTool outputs declared in IMAGE_TOOL_OUTPUTS.

property input_provenance_spec: ToolProvenanceSpec | None

Return the replay provenance snapshot for the displayed tool input data.

set_input_provenance_spec(provenance_spec)[source]

Set the replay provenance snapshot for the displayed tool input data.

set_input_provenance_parent_fetcher(fetcher)[source]

Set the callback used to resolve provenance for future source refreshes.

output_imagetool_data(output_id)[source]

Return the current data for a manager-tracked output declared in the class.

Subclasses should declare outputs in IMAGE_TOOL_OUTPUTS instead of overriding this method directly. The base implementation resolves output_id against that mapping and calls the declared data method.

output_imagetool_provenance(output_id, data)[source]

Return replay provenance for a manager-tracked output declared in the class.

Subclasses should declare outputs in IMAGE_TOOL_OUTPUTS instead of overriding this method directly. The base implementation resolves output_id against that mapping and resolves the declared provenance definition.

detached_output_imagetool_provenance(data, *, source=None)[source]

Return replay provenance for an unbound ImageTool opened from this tool.

Override this only when an unbound ImageTool should display different replay provenance from current_provenance_spec(). Standalone and managed detached launches both preserve the returned provenance, so this hook must stay free of blocking side effects such as warning dialogs.

copy_code()[source]

Copy the current tool provenance code to the clipboard.

property tool_status: M
property tool_data: DataArray
property source_spec: ToolProvenanceSpec | None

Return the current ImageTool source specification.

property source_binding: ImageToolSelectionSourceBinding | None

Return the ImageTool selection state used for source refreshes, if any.

property source_state: Literal['fresh', 'stale', 'unavailable']

Return whether the bound ImageTool source is fresh, stale, or unavailable.

property source_auto_update: bool

Return whether compatible source changes should be applied automatically.

property has_source_binding: bool

Return True when this tool is bound to ImageTool source data.

property source_status_text: str

Return the status label shown for source bindings that need attention.

set_source_binding(source_spec, *, source_binding=None, auto_update=False, state='fresh')[source]

Bind this tool to data selected from a parent ImageTool.

Parameters:
  • source_spec (ToolProvenanceSpec | None) – Current source spec used for derivation display and older saved workspaces. If source_binding is not provided, refresh applies this spec as stored.

  • source_binding (ImageToolSelectionSourceBinding | None, default: None) – Selection state from an ImageTool plot. When provided, refresh first builds a new source_spec from the current parent data.

  • auto_update (bool, default: False) – Whether compatible parent changes should update this tool automatically.

  • state (Literal['fresh', 'stale', 'unavailable'], default: "fresh") – Current refresh state for manager and tool status UI.

set_source_parent_fetcher(fetcher)[source]

Set the callback used to fetch the latest parent ImageTool data.

finalize_source_refresh()[source]

Record that the current source refresh has been applied to the tool.

reload_source_data()[source]

Reload this tool from its managed ImageTool source chain.

validate_update_data(new_data)[source]

Validate or normalize source data before update_data consumes it.

Subclasses can override this to enforce dimension, coordinate, or metadata requirements for refreshed source data. Raise an exception to mark the source as unavailable.

handle_parent_source_replaced(parent_data)[source]

React to replacement of the parent ImageTool data source.

show_source_update_dialog(*, parent=None)[source]

Show automatic update controls and apply the user’s selection.

update_data(new_data)[source]

Apply refreshed source data to the existing tool window.

Subclasses must override this when they support updates from ImageTool data. Return False to leave the tool marked as stale when the new data is recognized but cannot be published as a fresh result immediately.

property preview_imageitem: ImageItem | None

Get the ImageItem to be used for preview in the ImageTool manager.

property info_text: str

Get the HTML text to be shown in the ImageTool manager.

classmethod can_save_and_load()[source]

Check if this tool can be saved and restored.

to_dataset()[source]

Get the xarray.Dataset representation of the tool window.

Returns:

Dataset – A dataset containing the data and attributes needed to restore the tool.

Return type:

Dataset

classmethod from_dataset(ds, **kwargs)[source]

Restore a tool window from a xarray.Dataset.

Parameters:
  • ds (Dataset) – The dataset containing the saved tool data and attributes, as created by to_dataset().

  • **kwargs – Additional keyword arguments passed to the constructor.

to_file(filename)[source]

Save the data, state, title, and geometry of the tool to a file.

The saved netcdf dataset can be used to recreate the ImageTool with the class method from_file().

Parameters:

filename (str | PathLike) – The name of the target netcdf file.

classmethod from_file(filename, **kwargs)[source]

Restore a window from a file saved using to_file().

Parameters:
  • filename (str | PathLike) – The name of the file.

  • **kwargs – Additional keyword arguments passed to the constructor.

duplicate(**kwargs)[source]

Create a duplicate of the current tool window.

This method creates a new instance of the tool with the same data and state as the current one.

Parameters:

kwargs – Additional keyword arguments passed to the constructor of the new tool.

Returns:

tool – The duplicated tool window.

Return type:

Self

erlab.interactive.utils.copy_to_clipboard(content)[source]

Copy content to the clipboard.

Parameters:

content (str | list[str]) – The content to be copied. If a list of strings is passed, the strings are joined by newlines.

Returns:

str – The copied content.

Return type:

str

erlab.interactive.utils.file_loaders(file_name=None)[source]

Generate a dictionary of namefilters and loader functions for file dialogs.

Parameters:

file_name (str | PathLike | Iterable[str | PathLike] | None, default: None) – Name of the file to load. If provided, only the loaders that match the file name are returned. If an iterable of file names is provided, the loaders that match all file names are returned.

Returns:

dict – Dictionary of file loaders. The keys are name filters(argument to setNameFilter), and the values are tuples of the loader function and additional keyword arguments.

Return type:

dict[str, tuple[Callable, dict]]

erlab.interactive.utils.format_1d_numeric_array_code(values)[source]

Format one-dimensional numeric values as compact executable Python code.

This is intended for generated snippets where readability matters but exact values must still round-trip when executed. Uniform integer-like grids are written as np.arange(...), uniform floating-point grids as np.linspace(...), and other inputs fall back to the general array formatter used by _parse_single_arg().

erlab.interactive.utils.format_call_kwargs(d)[source]

Format mapping arguments for a call site.

If all keys are identifier strings, emit plain keyword syntax. If all keys are strings but at least one is not an identifier, emit **{...} so the generated call still uses keyword expansion. Non-string keys fall back to a positional mapping literal.

erlab.interactive.utils.format_kwargs(d)[source]

Format a dictionary of keyword arguments for a function call.

If the keys are valid Python identifiers, the output will be formatted as keyword arguments. Otherwise, the output will be formatted as a dictionary.

Parameters:

d (Mapping[Any, Any]) – Dictionary of keyword arguments.

erlab.interactive.utils.generate_code(func, args, kwargs, module=None, name=None, assign=None, prefix=None, remove_defaults=True, line_length=88, copy=False)[source]

Generate Python code for a function call.

The result can be copied to your clipboard in a form that can be pasted into an interactive Python session or Jupyter notebook cell.

Parameters:
  • func (Callable) – Function to generate code for.

  • args (Collection[Any]) – Positional arguments passed onto the function. Non-string arguments are converted to strings. If given a string, quotes are added. If surrounded by vertical bars (|), the string is not quoted.

  • kwargs (dict[str, Any]) – Keyword arguments passed onto the function.

  • module (str | None, default: None) – Prefix to add to the function name. For example, "scipy.ndimage".

  • name (str | None, default: None) – Name of the function. If None, func.__name__ is used.

  • assign (str | tuple[str, ...] | None, default: None) – If provided, the return value will be assigned to this variable. For multiple assignment, pass a tuple.

  • prefix (str | None, default: None) – Prefix to add to the generated string.

  • remove_defaults (bool, default: True) – If True, keyword arguments that have values identical to the defaults are removed.

  • line_length (int, default: 88) – Maximum length of the line. If the line is longer than this, it will be split into multiple lines.

  • copy (bool, default: False) – If True, the result is copied to the clipboard.

Examples

>>> import numpy as np
>>> from erlab.interactive.utils import generate_code
>>> generate_code(
>>>     np.linalg.norm,
>>>     args=["|np.array([1, 2, 3])|"],
>>>     kwargs=dict(ord=2, keepdims=False),
>>>     module="np.linalg",
>>>     assign="value",
>>> )
'value = np.linalg.norm(np.array([1, 2, 3]), ord=2)'
erlab.interactive.utils.load_fit_ui(*, parent=None)[source]

Load a fit result from a file.

When called, a file dialog is opened to select the file to load. The fit result is loaded from the selected file using xarray_lmfit.load_fit().

Parameters:

parent (QWidget | None, default: None) – Parent widget for the file dialog.

Returns:

result (xr.Dataset or None) – The loaded fit result. Returns None if no file was selected or if the file could not be loaded.

Return type:

Dataset | None

erlab.interactive.utils.load_ui(uifile, baseinstance=None)[source]

Load a Qt Designer .ui file with stable behavior under coverage tracing.

erlab.interactive.utils.make_crosshairs(n=1)[source]

Create a pyqtgraph.TargetItem and associated RotatableLines.

Parameters:

n (Literal[1, 2, 3], default: 1) – Number of lines to create. Must be 1, 2, or 3. If 1, a single line is created. If 2, two lines are created at 0 and 90 degrees. If 3, three lines are created at 0, 120, and 240 degrees.

erlab.interactive.utils.parse_data(data)[source]
erlab.interactive.utils.qt_is_valid(*objects)[source]

Return True only if every object is a valid Qt object.

For PySide, uses shiboken6.isValid to check validity.

For PyQt6, uses PyQt6.sip.isdeleted.

Parameters:

*objects (object) – Objects to validate. None values are ignored.

erlab.interactive.utils.save_fit_ui(fit_result, *, parent=None)[source]

Save a fit result to a file using a file dialog.

When called, a file dialog is opened to select the file name and format. The fit result dataset is saved to the selected file in the chosen format using xarray_lmfit.save_fit().

Parameters:
  • fit_result (Dataset) – The fit result to save.

  • parent (QWidget | None, default: None) – Parent widget for the file dialog.

erlab.interactive.utils.single_shot(receiver, msec, callback, *guards)[source]

Invoke a delayed callback without crashing if the receiver is deleted.

This is a safe wrapper around QtCore.QTimer.singleShot that checks the receiver with the active Qt binding’s validity predicate before invoking the callback. It avoids segmentation faults that can happen when a queued callback targets a deleted QObject.

In the original Qt implementation, singleShot takes a context object that is used to determine whether the callback should be invoked. But for some reason, this argument is not exposed in the Python bindings. This function implements similar functionality by checking the validity of the receiver and any additional guard objects.

Parameters:
  • receiver (QObject) – QObject that owns the callback. The callback is skipped if this object has been destroyed.

  • msec (int) – Delay in milliseconds.

  • callback (Callable[[], None]) – Zero-argument callable to invoke after the delay.

  • *guards (QObject | None) – Additional QObjects that must remain valid. If any guard is deleted, the callback is skipped.

erlab.interactive.utils.wait_dialog(parent, message)[source]

Show a wait dialog while executing a block of code.

This context manager creates a simple dialog with a message while the block of code is being executed. The dialog is closed when the block is done.

Parameters:
  • parent (QWidget) – Parent widget.

  • message (str) – Message to display in the dialog.

Example

>>> with wait_dialog(self, "Processing data..."):
>>>    some_long_running_code()
class erlab.interactive.utils.xImageItem(image=None, **kwargs)[source]

Bases: BetterImageItem

pyqtgraph.ImageItem with additional functionality.

This class provides xarray.DataArray support and auto limits based on histogram analysis.

Parameters:
Signals:

sigToleranceChanged()

quickMinMax(*args, **kwargs)[source]
getHistogram(*args, **kwargs)[source]
set_cut_tolerance(cut_tolerance)[source]
data_cut_levels(data=None)[source]

Return appropriate levels estimated from the data.

setImage(image=None, autoLevels=None, cut_to_data=False, **kargs)[source]
setDataArray(data, update_labels=True, **kargs)[source]
getMenu()[source]
getPlotItem()[source]
open_itool()[source]