# import system modules import sys # import project classes # import names from dialin.squish import utils, denaliMessages # Import PySide2 classes from PySide2.QtUiTools import QUiLoader from PySide2 import QtCore, QtWidgets from PySide2.QtCore import QFile, Slot from PySide2.QtGui import qApp class RunTimeWidget: """ the parent class of all the run time loadable widgets """ loader: QUiLoader window: QtWidgets.QWidget def __init__(self, ui_name: str): self.ui_name = ui_name self.loader = QUiLoader() self.__load_ui() def __load_ui(self): """ loads the ui file of the GUI at run time :return: none """ ui_file = QFile(self.ui_name) ui_file.open(QFile.ReadOnly) self.window = self.loader.load(ui_file) # assert if the ui file can't be loaded error = self.loader.errorString() assert len(error) == 0, error ui_file.close() def show(self): """ shows the main container window :return: none """ self.window.show() def __find_child(self, child_type, child_name: str) -> QtWidgets.QWidget: """ finds a child in the loaded ui and returns the reference to it if found otherwise quits the application :param child_type: (var) type of the child :param child_name: (str) name of the child :return: (QtWidgets.QWidget) reference to the child """ child: QtWidgets.QWidget = self.window.findChild(child_type, child_name) assert child != 0, "child name '{}' with type '{}' can't be found.".format(child_name, child_type) return child def find_label(self, name: str) -> QtWidgets.QLabel: """ convenient method of find_child for QLabel :param name: (str) name of the QLabel Object :return: (QLabel) reference to the QLabel """ child = self.__find_child(QtWidgets.QLabel, name) return child def find_button(self, name: str) -> QtWidgets.QPushButton: """ convenient method of find_child for QPushButton :param name: (str) name of the QPushButton Object :return: (QPushButton) reference to the QPushButton """ child = self.__find_child(QtWidgets.QPushButton, name) return child def find_combobox(self, name: str) -> QtWidgets.QComboBox: """ convenient method of find_child for QComboBox :param name: (str) name of the QComboBox Object :return: (QPushButton) reference to the QComboBox """ child = self.__find_child(QtWidgets.QComboBox, name) return child def find_spinbox(self, name: str) -> QtWidgets.QSpinBox: """ convenient method of find_child for QSpinBox :param name: (str) name of the QSpinBox Object :return: (QSpinBox) reference to the QSpinBox """ child = self.__find_child(QtWidgets.QSpinBox, name) return child def find_slider(self, name: str) -> QtWidgets.QSlider: """ convenient method of find_child for QSlider :param name: (str) name of the QSlider Object :return: (QSlider) reference to the QSlider """ child = self.__find_child(QtWidgets.QSlider, name) return child def find_table_widget(self, name: str) -> QtWidgets.QTableWidget: """ convenient method of find_child for QTableWidget :param name: (str) name of the QTableWidget Object :return: (QTableWidget) reference to the QTableWidget """ child: QtWidgets.QTableWidget = self.__find_child(QtWidgets.QTableWidget, name) return child class Simulator(RunTimeWidget): """ The simulator class which loads the ui file dynamically and initializes the objects and can be eventually shown. """ # global variables declarations ui_file_name = "SalineBolusSimulator.ui" # pushbutton btnSalineAccept: QtWidgets.QPushButton btnSalineReject: QtWidgets.QPushButton # label lblSalineAction: QtWidgets.QLabel # spinbox spnSalineRejectReason: QtWidgets.QSpinBox # combobox cmbSalineAcceptTarget: QtWidgets.QComboBox # sliders sldSalineTarget: QtWidgets.QSlider sldSalineCumulative: QtWidgets.QSlider sldSalineVolume: QtWidgets.QSlider # tables tblSalineSubMode: QtWidgets.QTableWidget tblSalineUFStates: QtWidgets.QTableWidget tblSalineSalineStates: QtWidgets.QTableWidget def __init__(self): super().__init__(Simulator.ui_file_name) self.initialize() def setup_saline_adjustment(self): """ sets up the treatment saline bolus adjustment GUI section :return: none """ self.btnSalineAccept = self.find_button('btnSalineAccept') self.btnSalineReject = self.find_button('btnSalineReject') self.lblSalineAction = self.find_label('lblSalineAction') self.spnSalineRejectReason = self.find_spinbox('spnSalineRejectReason') self.cmbSalineAcceptTarget = self.find_combobox('cmbSalineAcceptTarget') self.btnSalineAccept.clicked.connect(self.do_accept) self.btnSalineReject.clicked.connect(self.do_reject) def setup_saline_data(self): """ sets up the treatment saline bolus data sender GUI section :return: none """ self.sldSalineTarget = self.find_slider('sldSalineTarget') self.sldSalineCumulative = self.find_slider('sldSalineCumulative') self.sldSalineVolume = self.find_slider('sldSalineVolume') self.sldSalineTarget.valueChanged.connect(self.do_saline_data) self.sldSalineCumulative.valueChanged.connect(self.do_saline_data) self.sldSalineVolume.valueChanged.connect(self.do_saline_data) def setup_treatment_states(self): """ sets up the treatment saline bolus states GUI section :return: none """ self.tblSalineSubMode = self.find_table_widget('tblSalineSubMode') self.tblSalineUFStates = self.find_table_widget('tblSalineUFStates') self.tblSalineSalineStates = self.find_table_widget('tblSalineSalineStates') self.tblSalineSubMode.setCurrentCell(0, 0) self.tblSalineUFStates.setCurrentCell(0, 0) self.tblSalineSalineStates.setCurrentCell(0, 0) self.tblSalineSubMode.cellClicked.connect(self.do_saline_saline_state) self.tblSalineUFStates.cellClicked.connect(self.do_saline_saline_state) self.tblSalineSalineStates.cellClicked.connect(self.do_saline_saline_state) @Slot() def do_accept(self): """ the slot for accept saline bolus button :return: none """ target = self.cmbSalineAcceptTarget.currentText() denaliMessages.setSalineBolusResponse(True, 0, target) self.lblSalineAction.setText('Accepted ' + target) @Slot() def do_reject(self): """ the slot for accept saline bolus button :return: none """ reason = self.spnSalineRejectReason.value() denaliMessages.setSalineBolusResponse(False, reason, 0) self.lblSalineAction.setText('Rejected ' + "{}".format(reason)) @Slot() def do_saline_saline_state(self): """ the slot for saline bolus state change :return: none """ sub_mode = self.tblSalineSubMode.verticalHeaderItem(self.tblSalineSubMode.currentRow()).text() uf_state = self.tblSalineUFStates.verticalHeaderItem(self.tblSalineUFStates.currentRow()).text() saline = self.tblSalineSalineStates.verticalHeaderItem(self.tblSalineSalineStates.currentRow()).text() denaliMessages.setTreatmentStatesData(sub_mode, uf_state, saline) @Slot() def do_saline_data(self): """ the slot which is called to send the saline bolus data by calling the denaliMessage API setTreatmentSalineBolusData :return: none """ denaliMessages.setTreatmentSalineBolusData(self.sldSalineTarget.value(), self.sldSalineCumulative.value(), self.sldSalineVolume.value()) def initialize(self): """ initializes the class by calling it's initializer methods to make objects ready :return: none """ self.setup_saline_adjustment() self.setup_saline_data() self.setup_treatment_states() def main(): """ the main function which initializes the Simulator and starts it. :return: none """ utils.tstStart(__file__) # create qt application QtWidgets.QApplication(sys.argv) simulator = Simulator() simulator.show() utils.tstDone() # start qt application main loop sys.exit(qApp.exec_()) if __name__ == "__main__": QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_ShareOpenGLContexts) main()