MetaController

class MetaController(available_subclasses: Optional[Mapping[str, List[str]]] = None)

Bases: QObject

Base controller class that manages exactly one MetaView and MetaModel instance

Public Methods

Abstract Methods

These methods must be implemented by subclasses.

(none)

Concrete Methods

MetaController.discard_last_tab_action() → None

Drop the most recently recorded action without replaying anything.

For an action that was refused and left the figure unchanged - a plot of what is already shown, say. Undoing it instead cleared the figure and replayed the whole history, which redrew it with the current selection rather than the recorded one.

MetaController.display_write_status(status: bool) → None

Emit a message indicating whether data was successfully written.

Parameters:

status (bool) – True if write was successful, False otherwise.

MetaController.export_plot_data() → None

Export the currently cached plot data to a CSV file.

Attempts to retrieve cached plot data from the model, prompts the user for a filename, and saves the data as a CSV if available. If no data is cached, logs a warning.

MetaController.get_session_state() → Dict[str, Any]

Return extra tab-specific state to persist alongside this tab’s session history entry.

MainController calls this on every open tab immediately before writing session history to disk, and merges the result into that tab’s history entry. The base implementation returns an empty dict. A subclass that keeps state MainController cannot otherwise see (e.g. a filter list built entirely in the view) should override this, and override restore_session_state() to apply it back.

Returns:

Extra state to serialize into this tab’s session history entry.

Return type:

Dict[str, Any]

MetaController.handle_kill_all_workers(subclass: str, exiting: bool = False) → None

Kill all running workers for this tab, and say so on the display panel.

The panel message is skipped when exiting is set: the display widget is being torn down along with everything else, so writing to it at that point would be pointless at best.

Parameters:
  • subclass (str) – Name of the controller the request is addressed to; the request is ignored if it names a different one.

  • exiting (bool) – True when called from the application’s shutdown handler, which additionally blocks until each thread has finished.

MetaController.handle_kill_worker(subclass: str, identifier: str) → None

Kill the selected worker if it is running, and say so on the display panel.

Every branch reports to the user. Previously the success path logged at INFO, which is below the default log level and therefore invisible, while the two no-op paths logged at WARNING and so raised a modal dialog containing a repr of the whole worker dictionary - feedback was exactly inverted, and a user aborting an operation had no way to tell whether it had taken effect.

Parameters:
  • subclass (str) – Name of the controller the kill request is addressed to.

  • identifier (str) – Worker identifier in "key/channel" form.

MetaController.load_actions_from_json(filename: str) → None

Load and apply tab actions from a JSON file.

Parameters:

filename (str) – Path to the JSON file containing saved actions.

MetaController.relay_add_text_to_display(text: str, source: str) → None

Relay text from model or view to be displayed in the main text display widget

MetaController.restore_session_state(state: Dict[str, Any]) → None

Restore extra tab-specific state captured by get_session_state().

Called by MainController after this tab is freshly instantiated during session load, with that tab’s full history entry (including keys unrelated to session state, which implementations should ignore). The base implementation does nothing.

Parameters:

state (Dict[str, Any]) – This tab’s session history entry, as previously written by get_session_state().

MetaController.save_tab_actions(save_file: str | None = None) → None

Emit a signal to save the current tab action history to the specified file.

Parameters:

save_file (Optional[str]) – Optional path to the file where actions should be saved.

MetaController.set_plugin_instances(instances: Mapping[str, Mapping[str, object]]) → None

Receive the live data plugin instances and pass them to the Model.

Called by MainController whenever the app’s plugin set changes, on the same path that refreshes the plugin names the View shows in its comboboxes - so a rename or a re-instantiation cannot leave either of them stale.

Parameters:

instances (Mapping[str, Mapping[str, object]]) – metaclass name -> plugin key -> live instance

Returns:

None

Return type:

None

MetaController.update_available_plugins(available_plugins: Mapping[str, list[str]]) → None

Called whenever a new plugin is instantiated elsewhere in the app, to keep an up to date list of possible data sources for use by this plugin

Parameters:

available_plugins (Mapping[str, list[str]]) – dict of lists keyed by MetaClass, listing the identifiers of all instantiated plugins throughout the app

MetaController.update_tab_actions(history: dict | None = None, undo: bool = False) → None

Update or undo the current tab action history, and emit the updated state.

Parameters:
  • history (Optional[dict]) – Dictionary representing a new action to add.

  • undo (bool) – If True, removes the most recent action and reverts to the previous state.

Private Methods

Abstract Methods

These methods must be implemented by subclasses.

abstractmethod MetaController._init() → None

Build this tab’s View and Model, and do any other setup the tab needs.

Assigning both self.view and self.model is required rather than conventional: the constructor calls this and then immediately connects the two to each other, so leaving either unset raises AttributeError before the tab exists. kwargs given to the base constructor are available as attributes by the time this runs.

abstractmethod MetaController._setup_connections() → None

Set up any local connections between the subordinate view and model