""" the plugin loader class """ import os from dialin.squish.denaliMessages import txStates from dialin.squish.utils import check_can0 from PySide2 import QtWidgets from PySide2.QtCore import Qt from simulator.dynamicloader import DynamicLoader # it loads all the classes in plugin folder dynamically # so used * in here to load all from plugins import * from dialin import HDSimulator class Simulator(DynamicLoader): """ The simulator class which loads the ui file dynamically and initializes the objects and can be eventually shown. Note: this class is growing fast and seems like needs to be multiple classes """ mdiArea: QtWidgets.QMdiArea menuView: QtWidgets.QMenu lblStatusCANBus: QtWidgets.QLabel lblStatusMessages: QtWidgets.QLabel plugins = [] def __init__(self): super().__init__(os.path.dirname(__file__), HDSimulator(console_out=True)) self.saline_requested_state = txStates.SALINE_BOLUS_STATE_IDLE if self.__check_can_bus(): self.__init_plugins() self.__init_actions() def _init_loader(self): """ initializes the class by calling it's initializer methods to make objects ready :return: none """ self.lblStatusCANBus = self.find_label('lblStatusCANBus') self.lblStatusMessages = self.find_label('lblStatusMessages') self.mdiArea = self.find_widget(QtWidgets.QMdiArea, 'mdiArea') self.menuView = self.find_widget(QtWidgets.QMenu, 'menuView') self.action_show_all = self.find_action('actionShowAll') def _init_widgets(self): pass def _init_connections(self): pass def __init_plugins(self): """ initializes the widgets' properties :return: none """ # loading/registering plugins # the loaded_plugins has been filled and exposed # from within the __init__.py in the plugins folder # folders with '__' and '.' have been ignored. for plugin in available_plugins: self.__register_plugin(eval(plugin)(self.hd_simulator)) def __init_actions(self): """ initializes the widgets connections :return: none """ self.action_show_all.toggled.connect(self.set_all_windows_visible) def __create_actions(self, name: str, window: QtWidgets.QWidget): """ creates a menu action item with the name/title name and set to show/hide the plugin form object :param name: the action menu title :param window: the object to show/hide :return: false if the object is None """ if window is None: return False act = self.menuView.addAction(name) act.setCheckable(True) act.toggled.connect(window.setVisible) self.action_show_all.toggled.connect(act.setChecked) def __register_plugin(self, obj: DynamicLoader, add_separator: bool = False): """ creates the plugin object and adds it to the mdi and creates an action menu for it :param obj: the plugin object :return: False if the passed obj is None """ self.plugins.append(obj) wgt = obj.window sub = self.mdiArea.addSubWindow(wgt) sub.setWindowFlags(Qt.WindowMinimizeButtonHint | Qt.WindowTitleHint) sub.setWindowFlag(Qt.WindowMaximizeButtonHint, obj.canMaximize) sub.setVisible(obj.isVisible) title = wgt.windowTitle() self.__create_actions(title, sub) wgt.setWindowTitle(wgt.setWindowTitle(title.replace('&', ''))) if add_separator: self.menuView.addSeparator() def set_all_windows_visible(self, visible: bool): """ sets all the windows (in)visible :param visible: if true the windows are set to visible :return: None """ for sub in self.mdiArea.subWindowList(): sub.setVisible(visible) self.mdiArea.cascadeSubWindows() def __check_can_bus(self): """ checks if CANBus can0 presents :return: False if CANBus can0 is not present. """ ok, msg = check_can0() print(ok, msg) if ok: self.lblStatusCANBus.setStyleSheet('color: rgb(78, 154, 6);') self.lblStatusCANBus.setText('CANBus: can0') return ok else: self.lblStatusCANBus.setStyleSheet('color: rgb(239, 41, 41);') self.lblStatusCANBus.setText('CANBus \'can0\' not found')