Index: simulator/run.py =================================================================== diff -u -r87a1d3676f718f9f6328ac7c2b5da5aa1a0271c2 -r393fd43e9a1cbf6b25a0f107928a051a622b2be2 --- simulator/run.py (.../run.py) (revision 87a1d3676f718f9f6328ac7c2b5da5aa1a0271c2) +++ simulator/run.py (.../run.py) (revision 393fd43e9a1cbf6b25a0f107928a051a622b2be2) @@ -1,3 +1,5 @@ + +# import system modules import sys # import project classes @@ -7,183 +9,251 @@ # Import PySide2 classes from PySide2.QtUiTools import QUiLoader from PySide2 import QtCore, QtWidgets -from PySide2.QtCore import QFile, SIGNAL, Slot -import PySide2.QtWidgets +from PySide2.QtCore import QFile, Slot +from PySide2.QtGui import qApp -# global variables declarations -ui_file_name = "SalineBolusSimulator.ui" -# application -app: QtWidgets.QApplication -# main widget -window: QtWidgets.QWidget -# 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_app(): +class RunTimeWidget: """ - initializing the QApplication app - and the main container QWidget window. - :return: none + the parent class of all the run time loadable widgets """ - global app, window - app = QtWidgets.QApplication(sys.argv) - window = QtWidgets.QWidget() - window.resize(320, 240) + loader: QUiLoader + window: QtWidgets.QWidget -def start_app(): - """ - shows the main container window - :return: none - """ - global app, window - window.show() - sys.exit(app.exec_()) + 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 load_ui(): - """ - loads the ui file of the GUI - :return: none - """ - global app, window - ui_file = QFile(ui_file_name) - ui_file.open(QFile.ReadOnly) - loader = QUiLoader() - window = loader.load(ui_file) - ui_file.close() - window.setWindowTitle('Saline Bolus Simulator ' + QtCore.__version__) + 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 setup_saline_adjustment(): - """ - sets up the treatment saline bolus adjustment GUI section - :return: none - """ - global app, window - global btnSalineAccept, btnSalineReject - global lblSalineAction, spnSalineRejectReason, cmbSalineAcceptTarget - btnSalineAccept = window.findChild(QtWidgets.QPushButton, 'btnSalineAccept') - btnSalineReject = window.findChild(QtWidgets.QPushButton, 'btnSalineReject') - lblSalineAction = window.findChild(QtWidgets.QLabel, 'lblSalineAction') - spnSalineRejectReason = window.findChild(QtWidgets.QSpinBox, 'spnSalineRejectReason') - cmbSalineAcceptTarget = window.findChild(QtWidgets.QComboBox, 'cmbSalineAcceptTarget') - btnSalineAccept.clicked.connect(do_accept) - btnSalineReject.clicked.connect(do_reject) + 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 setup_saline_data(): - """ - sets up the treatment saline bolus data sender GUI section - :return: none - """ - global app, window - global sldSalineTarget, sldSalineCumulative, sldSalineVolume - sldSalineTarget = window.findChild(QtWidgets.QSlider, 'sldSalineTarget') - sldSalineCumulative = window.findChild(QtWidgets.QSlider, 'sldSalineCumulative') - sldSalineVolume = window.findChild(QtWidgets.QSlider, 'sldSalineVolume') - sldSalineTarget.valueChanged.connect(do_saline_data) - sldSalineCumulative.valueChanged.connect(do_saline_data) - sldSalineVolume.valueChanged.connect(do_saline_data) + 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 setup_treatment_states(): - """ - sets up the treatment saline bolus states GUI section - :return: none - """ - global app, window - global tblSalineSubMode, tblSalineUFStates, tblSalineSalineStates - tblSalineSubMode = window.findChild(QtWidgets.QTableWidget, 'tblSalineSubMode') - tblSalineUFStates = window.findChild(QtWidgets.QTableWidget, 'tblSalineUFStates') - tblSalineSalineStates = window.findChild(QtWidgets.QTableWidget, 'tblSalineSalineStates') - tblSalineSubMode.setCurrentCell(0, 0) - tblSalineUFStates.setCurrentCell(0, 0) - tblSalineSalineStates.setCurrentCell(0, 0) - tblSalineSubMode.cellClicked.connect(do_saline_saline_state) - tblSalineUFStates.cellClicked.connect(do_saline_saline_state) - tblSalineSalineStates.cellClicked.connect(do_saline_saline_state) + 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 -@Slot() -def do_accept(): + +class Simulator(RunTimeWidget): """ - the slot for accept saline bolus button - :return: none + The simulator class which loads the ui file dynamically and initializes the objects + and can be eventually shown. """ - target = cmbSalineAcceptTarget.currentText() - denaliMessages.setSalineBolusResponse(True, 0, target) - lblSalineAction.setText('Accepted ' + target) + # 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 -@Slot() -def do_reject(): - """ - the slot for accept saline bolus button - :return: none - """ - reason = spnSalineRejectReason.value() - denaliMessages.setSalineBolusResponse(False, reason, 0) - lblSalineAction.setText('Rejected ' + reason) + 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) -@Slot() -def do_saline_saline_state(row, column): - """ - the slot for saline bolus state change - :param row : row of the selected item in the list of saline bolus states - :param column: column of the selected item in the list of saline bolus states - :return: none - """ - sub_mode = tblSalineSubMode.verticalHeaderItem(tblSalineSubMode.currentRow()).text() - uf_state = tblSalineUFStates.verticalHeaderItem(tblSalineUFStates.currentRow()).text() - saline = tblSalineSalineStates.verticalHeaderItem(tblSalineSalineStates.currentRow()).text() - denaliMessages.setTreatmentStatesData(sub_mode, uf_state, saline) + 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_saline_data(): - """ - the slot which is called to send the saline bolus data - by calling the denaliMessage API setTreatmentSalineBolusData - :return: none - """ - denaliMessages.setTreatmentSalineBolusData(sldSalineTarget.value(), sldSalineCumulative.value(), - sldSalineVolume.value()) + @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__) - init_app() - load_ui() - setup_saline_adjustment() - setup_saline_data() - setup_treatment_states() - start_app() + + # 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() -