Пример #1
0
class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, config, esp32, *args, **kwargs):
        """
        Initializes the main window for the MVM GUI. See below for subfunction setup description.
        """

        super(MainWindow, self).__init__(*args, **kwargs)
        uic.loadUi('mainwindow.ui', self) # Load the .ui file

        self.config = config
        self.esp32 = esp32


        '''
        Instantiate the DataFiller, which takes
        care of filling plots data
        '''
        self.data_filler = DataFiller(config)

        '''
        Instantiate DataHandler, which will start a new
        thread to read data from the ESP32. We also connect
        the DataFiller to it, so the thread will pass the
        data directly to the DataFiller, which will
        then display them.
        '''
        self._data_h = DataHandler(config, self.esp32)
        self._data_h.connect_data_filler(self.data_filler)
        self._data_h.start_io_thread()


        '''
        Set up tool settings (bottom bar)

        self.toolsettings[..] are the objects that hold min, max values for a given setting as
        as the current value (displayed as a slider and as a number).
        '''
        toolsettings_names = {"toolsettings_1", "toolsettings_2", "toolsettings_3"}
        self.toolsettings = {};

        for name in toolsettings_names:
            toolsettings = self.findChild(QtWidgets.QWidget, name)
            toolsettings.connect_config(config)
            self.toolsettings[name] = toolsettings

        '''
        Set up data monitor/alarms (side bar)

        self.monitors[..] are the objects that hold monitor values and thresholds for alarm min
        and max. The current value and optional stats for the monitored value (mean, max) are set
        here.
        '''
        monitor_names = {"monitor_top", "monitor_mid", "monitor_bot"}
        self.monitors = {}
        monitor_default = {
                "name": "NoName",
                "min": 0,
                "init": 50,
                "max": 100,
                "step": None,
                "units": None,
                "dec_precision": 2,
                "color": "black",
                "alarmcolor": "red"}

        for name in monitor_names:
            monitor = self.findChild(QtWidgets.QWidget, name)
            entry = config.get(name, monitor_default)
            monitor.setup(
                    entry.get("name", monitor_default["name"]),
                    setrange=(
                        entry.get("min", monitor_default["min"]),
                        entry.get("init", monitor_default["init"]),
                        entry.get("max", monitor_default["max"])),
                    units=entry.get("units", monitor_default["units"]),
                    alarmcolor=entry.get("alarmcolor", monitor_default["alarmcolor"]),
                    color=entry.get("color", monitor_default["color"]),
                    step=entry.get("step", monitor_default["step"]),
                    dec_precision=entry.get("dec_precision", monitor_default["dec_precision"]))
            self.monitors[name] = monitor
        self.data_filler.connect_monitor('monitor_top', self.monitors['monitor_top'])
        self.data_filler.connect_monitor('monitor_mid', self.monitors['monitor_mid'])
        self.data_filler.connect_monitor('monitor_bot', self.monitors['monitor_bot'])
        # Need to add the other monitors...which ones?


        '''
        Set up plots (PyQtPlot)

        self.plots[..] are the PyQtPlot objects.
        '''
        self.plots = [];
        self.plots.append(self.findChild(QtWidgets.QWidget, "plot_top"))
        self.plots.append(self.findChild(QtWidgets.QWidget, "plot_mid"))
        self.plots.append(self.findChild(QtWidgets.QWidget, "plot_bot"))
        self.data_filler.connect_plot('monitor_top', self.plots[0])
        self.data_filler.connect_plot('monitor_mid', self.plots[1])
        self.data_filler.connect_plot('monitor_bot', self.plots[2])

        '''
        Set up start/stop auto/min mode buttons.

        Connect each to their respective mode toggle functions.
        The StartStopWorker class takes care of starting and stopping a run
        '''
        self.button_startstop = self.findChild(QtWidgets.QPushButton, "button_startstop")
        self.button_autoassist = self.findChild(QtWidgets.QPushButton, "button_autoassist")
        
        self._start_stop_worker = StartStopWorker(
                self, 
                self.config, 
                self.esp32, 
                self.button_startstop, 
                self.button_autoassist)

        self.button_startstop.released.connect(self._start_stop_worker.toggle_start_stop)
        self.button_autoassist.released.connect(self._start_stop_worker.toggle_mode)

        '''
        Connect settings button to Settings overlay.
        '''
        self.settings = Settings(config, self)
        self.button_settings = self.findChild(QtWidgets.QPushButton, "button_settings")
        self.button_settings.pressed.connect(self.settings.show)

        self.settings.connect_data_handler(self._data_h)
        self.settings.connect_toolsettings(self.toolsettings)
        self.settings.connect_start_stop_worker(self._start_stop_worker)
        self.settings.connect_workers()
        self.settings.load_presets_auto()
        self.settings.load_presets_assist()

    def closeEvent(self, event):
        self._data_h.stop_io()
Пример #2
0
class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, config, esp32, *args, **kwargs):
        """
        Initializes the main window for the MVM GUI. See below for subfunction setup description.
        """

        super(MainWindow, self).__init__(*args, **kwargs)
        uic.loadUi('mainwindow.ui', self) # Load the .ui file

        self.config = config
        self.esp32 = esp32

        '''
        Start the alarm handler, which will check for ESP alarms
        '''
        self.alarm_h = AlarmHandler(self.config, self.esp32)

        '''
        Get the toppane and child pages
        '''
        self.toppane    = self.findChild(QtWidgets.QStackedWidget, "toppane")
        self.main       = self.findChild(QtWidgets.QWidget,        "main")
        self.initial    = self.findChild(QtWidgets.QWidget,        "initial")
        self.startup    = self.findChild(QtWidgets.QWidget,        "startup")
        self.settings   = self.findChild(QtWidgets.QWidget,        "settings")


        '''
        Get the center pane (plots) widgets
        '''
        self.centerpane         = self.findChild(QtWidgets.QStackedWidget, "centerpane")
        self.plots_all          = self.findChild(QtWidgets.QWidget,        "plots_all")
        self.plots_settings     = self.findChild(QtWidgets.QWidget,        "plots_settings")
        self.plot_hidden_slots  = self.findChild(QtWidgets.QVBoxLayout,    "plot_hidden_slots")

        '''
        Get the bottombar and child pages
        '''
        self.bottombar       = self.findChild(QtWidgets.QStackedWidget, "bottombar")
        self.toolbar         = self.findChild(QtWidgets.QWidget,        "toolbar")
        self.menu            = self.findChild(QtWidgets.QWidget,        "menu")
        self.frozen_bot      = self.findChild(QtWidgets.QWidget,        "frozenplots_bottom")
        self.settingsbar     = self.findChild(QtWidgets.QWidget,        "settingsbar")
        self.blank           = self.findChild(QtWidgets.QWidget,        "blank")
        self.settingsfork    = self.findChild(QtWidgets.QWidget,        "settingsforkbar")
        self.alarmsbar       = self.findChild(QtWidgets.QWidget,        "alarmsbar")

        '''
        Get the stackable bits on the right
        '''
        self.rightbar     = self.main.findChild(QtWidgets.QStackedWidget, "rightbar")
        self.monitors_bar = self.main.findChild(QtWidgets.QWidget,        "three_monitors")
        self.frozen_right = self.main.findChild(QtWidgets.QWidget,        "frozenplots_right")

        '''
        Get initial and startup buttons
        '''
        self.button_new_patient    = self.initial.findChild(QtWidgets.QPushButton, "button_new_patient")
        self.button_resume_patient = self.initial.findChild(QtWidgets.QPushButton, "button_resume_patient")
        self.button_start_settings = self.startup.findChild(QtWidgets.QPushButton, "button_start_settings")
        self.button_start_vent     = self.startup.findChild(QtWidgets.QPushButton, "button_start_vent")
        self.button_start_test     = self.startup.findChild(QtWidgets.QPushButton, "button_start_test")

        '''
        Get toolbar widgets
        '''
        self.button_menu  = self.toolbar.findChild(QtWidgets.QPushButton, "button_menu")
        self.label_status = self.toolbar.findChild(QtWidgets.QLabel,      "label_status")

        toolsettings_names = {"toolsettings_1", "toolsettings_2", "toolsettings_3"}
        self.toolsettings = {};

        for name in toolsettings_names:
            toolsettings = self.toolbar.findChild(QtWidgets.QWidget, name)
            toolsettings.connect_config(config)
            self.toolsettings[name] = toolsettings

        '''
        Get menu widgets and connect settings for the menu widget
        '''
        self.button_back         = self.menu.findChild(QtWidgets.QPushButton, "button_back")
        self.button_settingsfork = self.menu.findChild(QtWidgets.QPushButton, "button_settingsfork")
        self.button_freeze       = self.menu.findChild(QtWidgets.QPushButton, "button_freeze")
        self.button_startstop    = self.menu.findChild(QtWidgets.QPushButton, "button_startstop")
        self.button_autoassist   = self.menu.findChild(QtWidgets.QPushButton, "button_autoassist")
        self.button_inspause     = self.menu.findChild(QtWidgets.QPushButton, "button_inspause")
        self.button_expause      = self.menu.findChild(QtWidgets.QPushButton, "button_expause")

        self.button_alarms       = self.settingsfork.findChild(QtWidgets.QPushButton, "button_alarms")
        self.button_settings     = self.settingsfork.findChild(QtWidgets.QPushButton, "button_settings")
        self.button_backsettings = self.settingsfork.findChild(QtWidgets.QPushButton, "button_backsettings")


        self.button_backalarms = self.alarmsbar.findChild(QtWidgets.QPushButton, "button_backalarms")
        self.button_applyalarm = self.alarmsbar.findChild(QtWidgets.QPushButton, "button_applyalarm")
        self.button_resetalarm = self.alarmsbar.findChild(QtWidgets.QPushButton, "button_resetalarm")
        self.button_topalarm   = self.alarmsbar.findChild(QtWidgets.QPushButton, "button_topalarm")
        self.button_midalarm   = self.alarmsbar.findChild(QtWidgets.QPushButton, "button_midalarm")
        self.button_botalarm   = self.alarmsbar.findChild(QtWidgets.QPushButton, "button_botalarm")

        '''
        Get frozen plots bottom bar widgets and connect
        '''
        self.button_unfreeze =   self.frozen_bot.findChild(QtWidgets.QPushButton, "button_unfreeze")

        '''
        Connect initial startup buttons
        '''
        self.button_resume_patient.pressed.connect(self.goto_resume_patient)
        self.button_new_patient.pressed.connect(self.goto_new_patient)
        self.button_start_vent.pressed.connect(self.goto_main)
        # TODO: connect to circuit test on ESP
        # self.button_start_test.pressed.connect()
        self.button_start_settings.pressed.connect(self.goto_settings)

        '''
        Connect back and menu buttons to toolbar and menu

        This effectively defines navigation from the bottombar.
        '''
        self.button_back.pressed.connect(self.show_toolbar)
        self.button_menu.pressed.connect(self.show_menu)
        self.button_freeze.pressed.connect(self.freeze_plots)
        self.button_unfreeze.pressed.connect(self.unfreeze_plots)
        self.button_alarms.pressed.connect(self.goto_alarms)
        self.button_settingsfork.pressed.connect(self.show_settingsfork)

        self.button_settings.pressed.connect(self.goto_settings)
        self.button_backsettings.pressed.connect(self.show_menu)

        self.button_backalarms.pressed.connect(self.exit_alarms)

        '''
        Instantiate the DataFiller, which takes
        care of filling plots data
        '''
        self.data_filler = DataFiller(config)

        '''
        Instantiate DataHandler, which will start a new
        thread to read data from the ESP32. We also connect
        the DataFiller to it, so the thread will pass the
        data directly to the DataFiller, which will
        then display them.
        '''
        self._data_h = DataHandler(config, self.esp32)
        self._data_h.connect_data_filler(self.data_filler)
        self._data_h.start_io_thread()

        self.menu.connect_datahandler_config(self._data_h, self.config)



        '''
        Set up tool settings (bottom bar)

        self.toolsettings[..] are the objects that hold min, max values for a given setting as
        as the current value (displayed as a slider and as a number).
        '''
        toolsettings_names = {"toolsettings_1", "toolsettings_2", "toolsettings_3"}
        self.toolsettings = {};

        for name in toolsettings_names:
            toolsettings = self.toolbar.findChild(QtWidgets.QWidget, name)
            toolsettings.connect_config(config)
            self.toolsettings[name] = toolsettings

        '''
        Set up data monitor/alarms (side bar) and plots

        self.monitors[..] are the objects that hold monitor values and thresholds for alarm min
        and max. The current value and optional stats for the monitored value (mean, max) are set
        here.
        '''
        monitor_slot_names = [
                "monitor_top_slot",
                "monitor_mid_slot",
                "monitor_bot_slot"]

        monitor_names = [
                "mon_inspiratory_pressure",
                "mon_tidal_volume",
                "mon_flow",
                "mon_oxygen_concentration"]

        plot_slot_names = [
                "plot_top_slot",
                "plot_mid_slot",
                "plot_bot_slot"]

        self.monitors = {}
        self.monitor_slots = {}
        self.plots = {};
        self.plot_slots = {}

        # Get displayed monitor slots
        for barname in monitor_slot_names:
            self.monitor_slots[barname] = self.rightbar.findChild(QtWidgets.QGridLayout, barname)

        # Get displayed plot slots
        for barname in plot_slot_names:
            self.plot_slots[barname] = self.main.findChild(QtWidgets.QGridLayout, barname)

        # Generate monitors and plots
        for name in monitor_names:
            monitor = Monitor(name, config, self.alarm_h,
                    self.config[name]["alarm_min_code"],
                    self.config[name]["alarm_max_code"])
            self.monitors[name] = monitor
            plot = pg.PlotWidget()
            self.plots[name] = plot

            # Make connections to data filler
            self.data_filler.connect_monitor(name, monitor)
            self.data_filler.connect_plot(name, plot)

        self.plots_settings.connect_monitors_and_plots(self)
        self.update_monitors_and_plots()
        self.button_applyalarm.pressed.connect(self.plots_settings.apply_selected)
        self.button_resetalarm.pressed.connect(self.plots_settings.reset_selected)
        self.button_topalarm.pressed.connect(lambda slotname=plot_slot_names[0]:
                self.plots_settings.display_selected(slotname))
        self.button_midalarm.pressed.connect(lambda slotname=plot_slot_names[1]:
                self.plots_settings.display_selected(slotname))
        self.button_botalarm.pressed.connect(lambda slotname=plot_slot_names[2]:
                self.plots_settings.display_selected(slotname))

        '''
        Set up start/stop auto/min mode buttons.

        Connect each to their respective mode toggle functions.
        The StartStopWorker class takes care of starting and stopping a run
        '''

        self._start_stop_worker = StartStopWorker(
                self,
                self.config,
                self.esp32,
                self.button_startstop,
                self.button_autoassist,
                self.toolbar)

        self.button_startstop.released.connect(self._start_stop_worker.toggle_start_stop)
        self.button_autoassist.released.connect(self._start_stop_worker.toggle_mode)

        '''
        Connect settings button to Settings overlay.
        '''
        self.settings = Settings(self)
        self.toppane.insertWidget(self.toppane.count(), self.settings)


    def update_monitors_and_plots(self):
        (self.active_monitors, self.active_plots) = self.plots_settings.populate_monitors_and_plots()
        # Connect buttons on freeze menus
        self.frozen_bot.connect_workers(self.data_filler, self.active_plots)
        self.frozen_right.connect_workers(self.active_plots)


    def goto_new_patient(self):
        # TODO : implement start from default_settings
        self.show_startup()

    def goto_resume_patient(self):
        # TODO : implement start from current_settings.json
        self.show_startup()

    def goto_settings(self):
        self.show_settings()
        self.show_settingsbar()

    def goto_main(self):
        self.show_main()
        self.show_toolbar()

    def exit_settings(self):
        self.show_main()
        self.show_menu()

    def goto_alarms(self):
        self.show_alarms()
        self.show_alarmsbar()
        self.plots_settings.config_monitors()

    def exit_alarms(self):
        self.show_menu()
        self.show_plots()
        self.plots_settings.deconfig_monitors()

    def show_settings(self):
        self.toppane.setCurrentWidget(self.settings)
        self.settings.tabWidget.setFocus()

    def show_startup(self):
        self.toppane.setCurrentWidget(self.startup)

    def show_menu(self):
        self.bottombar.setCurrentWidget(self.menu)

    def show_toolbar(self):
        self.bottombar.setCurrentWidget(self.toolbar)

    def show_settingsbar(self):
        self.bottombar.setCurrentWidget(self.settingsbar)

    def show_main(self):
        self.toppane.setCurrentWidget(self.main)

    def show_settingsfork(self):
        self.bottombar.setCurrentWidget(self.settingsfork)

    def show_alarms(self):
        self.centerpane.setCurrentWidget(self.plots_settings)

    def show_plots(self):
        self.centerpane.setCurrentWidget(self.plots_all)

    def show_alarmsbar(self):
        self.bottombar.setCurrentWidget(self.alarmsbar)

    def freeze_plots(self):
        self.data_filler.freeze()
        self.rightbar.setCurrentWidget(self.frozen_right)
        self.bottombar.setCurrentWidget(self.frozen_bot)


    def unfreeze_plots(self):
        self.data_filler.unfreeze()
        self.rightbar.setCurrentWidget(self.monitors_bar)
        self.show_menu()

    def closeEvent(self, event):
        self._data_h.stop_io()