Source code for pymodaq.extensions.sequencer.utilities.elements.sequence

import weakref
from typing import TYPE_CHECKING, Any, Union
import numpy as np


from qtpy import QtWidgets, QtCore

from serializall import SerializableFactory
from pymodaq_data import DataToExport

from pymodaq_gui.utils.widgets.combo import ComboBox
from pymodaq.extensions.sequencer.utilities.element_factory import SeqEltBase, SeqEltFactory, ElementError
from pymodaq.extensions.sequencer.utilities.widget_with_toolbar import WidgetWithToolbar
from pymodaq_utils.utils import find_objects_in_list_from_attr_name_val

if TYPE_CHECKING:
    from pymodaq.extensions.sequencer.utilities.sequencer.sequence import Sequence


ser_factory = SerializableFactory()

[docs] @SerializableFactory.register_decorator() @SeqEltFactory.register_elt() class SequenceElt(SeqEltBase): elt_name = 'sequence' children_allowed = False sequences: list['Sequence'] = [] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._sequence: str = None self.sequence: str = None if len(self.get_sequences_name()) == 0 else self.get_sequences_name()[0] self._combo: weakref.ref[ComboBox] | None = None # weakref to the combobox holding the states @classmethod def register_sequence(cls, sequence: 'Sequence'): if sequence.title not in [seq.title for seq in cls.sequences]: cls.sequences.append(sequence) @classmethod def unregister_sequence(cls, sequence: 'Sequence'): if sequence.title in [seq.title for seq in cls.sequences]: cls.sequences.remove(sequence)
[docs] def get_sequences(self) -> list['Sequence']: """ Get the list of Sequences that can be started, removing the one this element belong to""" sequences = list(self.sequences) if self.parent_sequence is not None: sequences.remove(find_objects_in_list_from_attr_name_val( sequences, 'title', self.parent_sequence.title)[0]) return sequences
[docs] def get_sequences_name(self) -> list[str]: """ Get the list of Sequences that can be started, removing the one this element belong to""" return [seq.title for seq in self.get_sequences()]
[docs] def do_things_with_parent_sequence(self): """ If this Element is using the Dashboard, once its setter has been called, this method will be executed Do whatever is needed to instantiate your element with the Dashboard """ pass
#self.sequence: str = None if len(self.get_sequences_name()) == 0 else self.get_sequences_name()[0] @property def sequence_obj(self) -> Union['Sequence', None]: match = find_objects_in_list_from_attr_name_val( self.get_sequences(), 'title', self.sequence) if len(match) > 0: return match[0] return None @property def sequence(self) -> str: return self._sequence @sequence.setter def sequence(self, value: str): self._sequence = value self.mstate.clear_transitions() self.mstate.add_external_transition(self.sequence_obj.machine.finished, self.mstate.done_state) def update_combo_sequences(self): if self._combo is not None and self._combo() is not None: self._combo().set_items(self.get_sequences_name()) @QtCore.Slot(str) def set_sequence(self, value: str): self.sequence = value def do_things_with_dashboard(self): pass def _create_widget(self, base_widget:WidgetWithToolbar) -> WidgetWithToolbar: combo = ComboBox(base_widget) combo.set_items(self.get_sequences_name()) base_widget.add_widget_top(combo) combo.setCurrentText(self.sequence) combo.currentTextChanged.connect(self.set_sequence) self._combo = weakref.ref(combo) return base_widget def _execute(self, dte: DataToExport = None): self.sequence_obj.start_sequence()
[docs] def to_dict_custom(self) -> dict[str, Any]: """ adds attribute to a dict in order to produce a human readable representation/configuration for this element to be reimplemented """ return {'sequence': self.sequence, }
[docs] def from_dict_custom(self, dict_config: dict[str, Any]): """ Create/set the custom part of the element to finish initialization using setters, attribute assignment or methods """ self.sequence = dict_config.pop('sequence')
def _eq(self, other: 'SequenceElt'): """ Custom method to reimplement to assert two elements are equals""" return (self.sequence == other.sequence) def __repr__(self): return f'{super().__repr__()} - {self.sequence}'
[docs] def check_set_is_valid(self) -> bool: """ Check the validity of the element Will be called before executing the element. Try to make sure the element is valid or return None if the user may do something! """ pass