Commit 05db8768 authored by Karol Hennessy's avatar Karol Hennessy

Merge branch 'ui_dev' into test_UI_new_state_machines_merge

parents d7013674 fabb9426
Pipeline #1589 failed with stages
......@@ -7,12 +7,15 @@ Command-line arguments:
-d, --debug : set the level of debug output.Include once for INFO, twice for DEBUG
-w, --windowed : run the user interface in windowed mode.
-r, --resolution : set the window size in pixels. E.g. -r 1920x1080
--no-startup : start the UI without going through the calibration startup sequence.
-l, --language : set the initial language for the UI (can later be set within the
interface). Defaults to English.
"""
__author__ = ["Benjamin Mummery", "Dónal Murray", "Tiago Sarmento"]
__credits__ = ["Benjamin Mummery", "Dónal Murray", "Tim Powell", "Tiago Sarmento"]
__license__ = "GPL"
__version__ = "0.1.1"
__version__ = "0.1.2"
__maintainer__ = "Benjamin Mummery"
__email__ = "benjamin.mummery@stfc.ac.uk"
__status__ = "Prototype"
......@@ -113,6 +116,9 @@ class NativeUI(HEVClient, QMainWindow):
):
super().__init__(*args, **kwargs)
# store variable to change editability of screen - implemented in screen locking
self.enableState = True
# Set the resolution of the display window
self.screen_width = resolution[0]
self.screen_height = resolution[1]
......@@ -148,8 +154,12 @@ class NativeUI(HEVClient, QMainWindow):
# Set up fonts based on the screen resolution. text_font and value_font are 20
# and 40px respectively for 1920*1080.
self.text_font = QFont("Sans Serif", resolution[0] / 96)
self.value_font = QFont("Sans Serif", 2 * resolution[0] / 96)
self.text_font = QFont("Sans Serif", int(resolution[0] / 96))
self.value_font = QFont("Sans Serif", int(2 * resolution[0] / 96))
# Set the popup size based on the screen resolution. alarm_popup_width is 400
# for 1920*1080
self.alarm_popup_width = int(resolution[0] / 4.8)
# Import icons
self.icons = {
......@@ -157,6 +167,7 @@ class NativeUI(HEVClient, QMainWindow):
"button_alarms_page": "exclamation-triangle-solid",
"button_modes_page": "fan-solid",
"button_settings_page": "sliders-h-solid",
"lock_screen": "lock-solid",
}
self.iconext = "png"
self.iconpath = self.__find_icons(self.iconext)
......@@ -169,6 +180,8 @@ class NativeUI(HEVClient, QMainWindow):
palette = self.palette()
palette.setColor(QPalette.Window, self.colors["page_background"])
self.alt_palette = self.palette()
# Set up the handlers
self.battery_handler = BatteryHandler()
self.data_handler = DataHandler(plot_history_length=1000)
......@@ -324,7 +337,8 @@ class NativeUI(HEVClient, QMainWindow):
)
)
# TODO: command sending
# Startup next and skip buttons should move from the startup widget to the main
# display
self.widgets.nextButton.pressed.connect(
lambda: self.display_stack.setCurrentWidget(self.main_display)
)
......@@ -332,6 +346,12 @@ class NativeUI(HEVClient, QMainWindow):
lambda: self.display_stack.setCurrentWidget(self.main_display)
)
self.widgets.lock_button.PageButtonPressed.connect(self.toggle_editability)
# Startup next button should send the ventilator start command.
self.widgets.nextButton.pressed.connect(
lambda: self.q_send_cmd("GENERAL", "START")
)
# Battery Display should update when we get battery info
self.battery_handler.UpdateBatteryDisplay.connect(
self.widgets.battery_display.update_status
......@@ -372,6 +392,12 @@ class NativeUI(HEVClient, QMainWindow):
lambda: self.display_stack.setCurrentWidget(self.startupWidget)
)
self.typeValPopupNum.okButton.pressed.connect(
self.typeValPopupNum.handle_ok_press
)
self.typeValPopupAlpha.okButton.pressed.connect(
self.typeValPopupNum.handle_ok_press
)
##### Mode:
# When mode is switched from mode page, various other locations must respond
for widget in self.mode_handler.spinDict.values():
......@@ -433,18 +459,26 @@ class NativeUI(HEVClient, QMainWindow):
button_widget.pressed.connect(
lambda i=key: self.mode_handler.handle_okbutton_click(i)
)
button_widget.pressed.connect(self.clinical_handler.commandSent)
elif isinstance(button_widget, CancelButtonWidget):
mode = self.mode_handler.get_mode(key)
button_widget.pressed.connect(self.mode_handler.commandSent)
buttonMode = self.mode_handler.get_mode(key)
button_widget.pressed.connect(
lambda i=buttonMode: self.mode_handler.handle_cancel_pressed(i)
)
button_widget.pressed.connect(
lambda i=buttonMode: self.clinical_handler.handle_cancel_pressed(i)
)
for key, button_widget in self.mode_handler.mainButtonDict.items():
if isinstance(button_widget, (OkButtonWidget)):
button_widget.clicked.connect(
self.mode_handler.handle_mainokbutton_click
)
button_widget.pressed.connect(self.clinical_handler.commandSent)
elif isinstance(button_widget, CancelButtonWidget):
# mode = self.mode_handler.get_mode(key)
button_widget.clicked.connect(self.mode_handler.commandSent)
button_widget.pressed.connect(self.clinical_handler.commandSent)
for key, spin_widget in self.clinical_handler.limSpinDict.items():
spin_widget.simpleSpin.manualChanged.connect(
......@@ -472,8 +506,8 @@ class NativeUI(HEVClient, QMainWindow):
self.clinical_handler.handle_cancelbutton_click
)
# for widget in (self.clinical_handler.setSpinDict.values()):
# self.clinical_handler.UpdateClinical.connect(widget.update_value)
for widget in self.clinical_handler.setSpinDict.values():
self.clinical_handler.UpdateClinical.connect(widget.update_value)
self.mode_handler.OpenPopup.connect(self.messageCommandPopup.populatePopup)
self.mode_handler.OpenPopup.connect(
......@@ -500,6 +534,13 @@ class NativeUI(HEVClient, QMainWindow):
)
##### Expert Settings:
self.widgets.expert_password_widget.okButton.pressed.connect(
self.widgets.expert_password_widget.submit_password
)
self.widgets.expert_password_widget.correctPassword.connect(
lambda: self.widgets.expert_passlock_stack.setCurrentIndex(1)
)
# Expert handler should respond to manual value changes
for key, spin_widget in self.expert_handler.spinDict.items():
spin_widget.simpleSpin.manualChanged.connect(
......@@ -640,12 +681,30 @@ class NativeUI(HEVClient, QMainWindow):
return 0
def toggle_editability(self):
"""Set all widgets disabled to lock screen"""
self.enableState = not self.enableState
if self.enableState:
self.alt_palette.setColor(QPalette.Window, self.colors["page_background"])
else:
self.alt_palette.setColor(QPalette.Window, self.colors["page_foreground"])
self.setPalette(self.alt_palette)
for attribute in dir(self.widgets):
widg = self.widgets.get_widget(attribute)
if isinstance(widg, QWidget):
widg.setEnabled(self.enableState)
self.widgets.lock_button.setEnabled(True)
@Slot(str)
def change_page(self, page_to_show: str) -> int:
"""
Change the page shown in page_stack.
"""
self.widgets.page_stack.setCurrentWidget(getattr(self.widgets, page_to_show))
self.widgets.expert_passlock_stack.setCurrentIndex(
0
) # reset password lock on expert settings
return 0
@Slot(str, str, float)
......@@ -656,12 +715,9 @@ class NativeUI(HEVClient, QMainWindow):
logging.debug("to MCU: cmd: %s", cmd)
check = self.send_cmd(cmdtype=cmdtype, cmd=cmd, param=param)
if check:
print("confirmed this command " + cmdtype + " " + cmd)
self.confirmPopup.addConfirmation(cmdtype + " " + cmd)
print("added popup")
return 0
else:
print("failed this command " + cmdtype + " " + cmd)
return 1
@Slot(str)
......
......@@ -24,6 +24,7 @@ class AlarmWidget(QtWidgets.QWidget):
def __init__(self, NativeUI, abstractAlarm, alarmCarrier, *args, **kwargs):
super(AlarmWidget, self).__init__(*args, **kwargs)
popup_height = int(NativeUI.alarm_popup_width / 10.0)
self.NativeUI = NativeUI
self.alarmCarrier = alarmCarrier # Needs to refer to its containing object
......@@ -37,27 +38,28 @@ class AlarmWidget(QtWidgets.QWidget):
iconpath_check = os.path.join(
self.NativeUI.iconpath, "exclamation-triangle-solid.png"
)
pixmap = QtGui.QPixmap(iconpath_check).scaledToHeight(40)
pixmap = QtGui.QPixmap(iconpath_check).scaledToHeight(popup_height)
iconLabel.setPixmap(pixmap)
self.layout.addWidget(iconLabel)
self.textLabel = QtWidgets.QLabel()
alarmLevel = self.alarmPayload["alarm_type"].replace('PRIORITY_', '')
alarmLevel = self.alarmPayload["alarm_type"] # .replace('PRIORITY_', '')
self.textLabel.setText(
alarmLevel + " - " + self.alarmPayload["alarm_code"]
self.alarmPayload["alarm_code"] + " - (" + alarmLevel + ")"
)
self.textLabel.setFixedWidth(400)
self.textLabel.setFixedWidth(NativeUI.alarm_popup_width)
self.textLabel.setAlignment(QtCore.Qt.AlignCenter)
self.textLabel.setFont(NativeUI.text_font)
#self.textLabel.setStyleSheet("font-size: " + NativeUI.text_size + ";")
# self.textLabel.setStyleSheet("font-size: " + NativeUI.text_size + ";")
self.layout.addWidget(self.textLabel)
self.setFixedHeight(40)
self.setFixedHeight(popup_height)
self.setLayout(self.layout)
if self.alarmPayload["alarm_type"] == "PRIORITY_HIGH":
self.setStyleSheet("background-color:red;")
elif self.alarmPayload["alarm_type"] == "PRIORITY_MEDIUM":
self.setStyleSheet("background-color:orange;")
self.setFixedSize(NativeUI.alarm_popup_width + popup_height, popup_height)
# self.timer = QtCore.QTimer()
# self.timer.setInterval(500) # just faster than 60Hz
......@@ -66,14 +68,13 @@ class AlarmWidget(QtWidgets.QWidget):
self.installEventFilter(self)
def eventFilter(self, source, event):
if (event.type() == QtCore.QEvent.MouseButtonPress):
if event.type() == QtCore.QEvent.MouseButtonPress:
self.NativeUI.widgets.page_buttons.alarms_button.click()
return False
def get_priority(self):
return self.alarmPayload["alarm_type"]
def setFont(self, font) -> int:
"""
Set the font for textLabel.
......@@ -95,12 +96,13 @@ class AlarmWidget(QtWidgets.QWidget):
class AlarmPopup(QtWidgets.QDialog):
"""Container class for alarm widgets. Handles ordering and positioning of alarms.
Needs to adjust its size whenever a widget is deleted"""
def __init__(self, NativeUI, *args, **kwargs):
super(AlarmPopup, self).__init__(*args, **kwargs)
self.setParent(NativeUI) # ensures popup closes when main UI does
self.alarmDict = {}
self.NativeUI = NativeUI
self.extraAlarms = AlarmExtrasWidget(NativeUI,self)
self.extraAlarms = AlarmExtrasWidget(NativeUI, self)
self.layout = QtWidgets.QVBoxLayout()
self.layout.setSpacing(0)
......@@ -141,7 +143,7 @@ class AlarmPopup(QtWidgets.QDialog):
self.NativeUI, abstractAlarm, self
)
self.refresh_alarm_ordering()
#self.layout.addWidget(self.alarmDict[abstractAlarm.alarmPayload["alarm_code"]])
# self.layout.addWidget(self.alarmDict[abstractAlarm.alarmPayload["alarm_code"]])
return 0
def removeAlarm(self, abstractAlarm):
......@@ -157,25 +159,26 @@ class AlarmPopup(QtWidgets.QDialog):
self.layout.removeWidget(self.alarmDict[key])
for key in self.alarmDict:
if self.alarmDict[key].get_priority() == 'PRIORITY_HIGH':
if self.alarmDict[key].get_priority() == "PRIORITY_HIGH":
if self.layout.count() == 4:
self.extraAlarms.update_text(1 + len(self.alarmDict) - self.layout.count())
self.extraAlarms.update_text(
1 + len(self.alarmDict) - self.layout.count()
)
self.layout.addWidget(self.extraAlarms)
break
self.layout.addWidget(self.alarmDict[key])
if self.layout.count() < 5:
for key in self.alarmDict:
if self.layout.count() == 3:
self.extraAlarms.update_text(len(self.alarmDict) - self.layout.count())
self.extraAlarms.update_text(
len(self.alarmDict) - self.layout.count()
)
self.layout.addWidget(self.extraAlarms)
break
if self.alarmDict[key].get_priority() == 'PRIORITY_LOW':
if self.alarmDict[key].get_priority() == "PRIORITY_LOW":
self.layout.addWidget(self.alarmDict[key])
# def resetTimer(self, alarmPayload):
# self.alarmDict[alarmPayload["alarm_code"]].timer.start()
......@@ -188,49 +191,52 @@ class AlarmPopup(QtWidgets.QDialog):
return 0
class AlarmExtrasWidget(QtWidgets.QWidget):
"""Object containing information particular to one alarm.
Created when alarm received from microcontroller, timeout after alarm signal stops.
Is contained within alarmPopup"""
def __init__(self, NativeUI, alarmCarrier, *args, **kwargs):
super(AlarmExtrasWidget, self).__init__(*args, **kwargs)
popup_height = int(NativeUI.alarm_popup_width / 10.0)
self.NativeUI = NativeUI
self.alarmCarrier = alarmCarrier # Needs to refer to its containing object
self.alarmCarrier = alarmCarrier # Needs to refer to its containing object
self.layout = QtWidgets.QHBoxLayout()
self.layout.setSpacing(0)
self.layout.setMargin(0)
#self.alarmPayload = abstractAlarm.alarmPayload
# self.alarmPayload = abstractAlarm.alarmPayload
iconLabel = QtWidgets.QLabel()
iconpath_check = os.path.join(
self.NativeUI.iconpath, "exclamation-triangle-solid.png"
)
pixmap = QtGui.QPixmap(iconpath_check).scaledToHeight(40)
pixmap = QtGui.QPixmap(iconpath_check).scaledToHeight(popup_height)
iconLabel.setPixmap(pixmap)
self.layout.addWidget(iconLabel)
self.textLabel = QtWidgets.QLabel()
self.textLabel.setText('1 More Alarms')
self.textLabel.setFixedWidth(400)
self.textLabel.setText("1 More Alarms")
self.textLabel.setFixedWidth(NativeUI.alarm_popup_width)
self.textLabel.setAlignment(QtCore.Qt.AlignCenter)
self.textLabel.setFont(NativeUI.text_font)
#self.textLabel.setStyleSheet("font-size: " + NativeUI.text_size + ";")
# self.textLabel.setStyleSheet("font-size: " + NativeUI.text_size + ";")
self.layout.addWidget(self.textLabel)
self.setFixedHeight(40)
self.setFixedHeight(popup_height)
self.setLayout(self.layout)
self.setStyleSheet("background-color:red;")
#self.priority = "PRIORITY_LOW"
# self.priority = "PRIORITY_LOW"
self.installEventFilter(self)
self.setFixedSize(NativeUI.alarm_popup_width + popup_height, popup_height)
def update_text(self, num):
self.textLabel.setText(str(num)+ ' More Alarms')
self.textLabel.setText(str(num) + " More Alarms")
def eventFilter(self, source, event):
if (event.type() == QtCore.QEvent.MouseButtonPress):
if event.type() == QtCore.QEvent.MouseButtonPress:
self.NativeUI.widgets.page_buttons.alarms_button.click()
return False
......
......@@ -19,10 +19,10 @@ from datetime import datetime
class AlarmTable(QtWidgets.QTableWidget):
"""Table containing all of the alarms since power up are contained. Easily sorted"""
def __init__(self, NativeUI, *args, **kwargs):
super(AlarmTable, self).__init__(*args, **kwargs)
self.alarmDict = {}
self.setSizePolicy(
QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding
)
......@@ -40,40 +40,33 @@ class AlarmTable(QtWidgets.QTableWidget):
self.payloadKeys = ["alarm_type", "alarm_code"]
self.resizeColumnsToContents()
self.alarmDict = {}
self.alarmCellDict = {}
self.timer = QtCore.QTimer()
self.timer.setInterval(100)
# self.timer.timeout.connect(self.updateDuration)
self.timer.start()
def addAlarm(self, abstractAlarm):
timestamp = str(datetime.now())[:-3]
newItem = QtWidgets.QListWidgetItem(
self.solidBell,
timestamp
+ ": "
+ abstractAlarm.alarmPayload["alarm_type"]
+ " - "
+ abstractAlarm.alarmPayload["alarm_code"],
)
self.insertItem(0, newItem) # add to the top
# self.labelList
# widg = self.cellWidget(rowNumber, 4)
# cellItem.setText(str(abstractAlarm.duration))
# abstractAlarm.alarmExpired.connect(lambda i =newItem, j = abstractAlarm: self.update_duration(i,j))
# self.setItem(self.nrows, colnum, newItem)
# tableItem.setText(str(abstractAlarm.duration))
def removeAlarm(self, abstractAlarm):
for x in range(self.count() - 1):
if abstractAlarm.alarmPayload["alarm_code"] in self.item(x).text():
self.takeItem(x)
# def addAlarm(self, abstractAlarm):
# timestamp = str(datetime.now())[:-3]
# newItem = QtWidgets.QListWidgetItem(
# self.solidBell,
# timestamp
# + ": "
# + abstractAlarm.alarmPayload["alarm_type"]
# + " - "
# + abstractAlarm.alarmPayload["alarm_code"],
# )
# self.insertItem(0, newItem) # add to the top
# def removeAlarm(self, abstractAlarm):
# for x in range(self.count() - 1):
# if abstractAlarm.alarmPayload["alarm_code"] in self.item(x).text():
# self.takeItem(x)
def addAlarmRow(self, abstractAlarm):
"""Add a new row 1 cell at a time. Goes through alarm payload to fill information"""
self.setSortingEnabled(False)
self.setRowCount(self.nrows + 1)
colnum = 0
newItem = QtWidgets.QTableWidgetItem(str(abstractAlarm.startTime)[:-3])
self.setItem(self.nrows, 0, newItem)
......@@ -85,26 +78,20 @@ class AlarmTable(QtWidgets.QTableWidget):
self.setItem(self.nrows, 2, newItem)
newItem = QtWidgets.QTableWidgetItem(" ")
self.alarmDict[self.nrows] = newItem
self.setItem(self.nrows, 3, self.alarmDict[self.nrows])
# abstractAlarm.alarmExpired.connect(lambda i = self.alarmDict[self.nrows], j = abstractAlarm: self.update_duration(i,j))
self.alarmCellDict[self.nrows] = newItem
self.setItem(self.nrows, 3, self.alarmCellDict[self.nrows])
# abstractAlarm.alarmExpired.connect(lambda i = self.alarmCellDict[self.nrows], j = abstractAlarm: self.update_duration(i,j))
self.timer.timeout.connect(
lambda i=self.alarmDict[self.nrows], j=abstractAlarm: self.update_duration(
lambda i=self.alarmCellDict[self.nrows], j=abstractAlarm: self.update_duration(
i, j
)
)
if self.nrows == 1:
self.resizeColumnsToContents()
#if self.nrows == 1:
self.resizeColumnsToContents()
self.nrows = self.nrows + 1
self.setSortingEnabled(True)
def update_duration(self, cellItem, abstractAlarm):
cellItem.setText(str(abstractAlarm.duration))
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
widg = alarmList()
widg.show()
sys.exit(app.exec_())
......@@ -2,7 +2,7 @@
"settings":[
[["APNEA", "ms", "APNEA", "SET_THRESHOLD_MIN", "APNEA", 5, 20, 10, 1, 0]],
[["Check Pressure Patient", "ms", "CHECK_P_PATIENT", "SET_THRESHOLD_MIN", "CHECK_P_PATIENT"],["Check Pressure Patient", "ms", "CHECK_P_PATIENT", "SET_THRESHOLD_MAX", "CHECK_P_PATIENT"]],
[["FIO2", "%", "HIGH_FIO2", "SET_THRESHOLD_MIN", "HIGH_FIO2", -10, 0, -5, 0.1, 1],["Percentage O2", "", "fiO2_percent", "SET_TARGET_CURRENT", "FIO2_PERCENT", 20, 100, 21, 1, 0],["FIO2", "%", "HIGH_FIO2", "SET_THRESHOLD_MAX", "HIGH_FIO2", 0, 10, 5, 0.1, 1]],
[["FIO2", "%", "HIGH_FIO2", "SET_THRESHOLD_MIN", "HIGH_FIO2", -10, 0, -5, 1, 0],["Percentage O2", "", "fiO2_percent", "SET_TARGET_CURRENT", "FIO2_PERCENT", 0, 100, 51, 1, 0],["FIO2", "%", "HIGH_FIO2", "SET_THRESHOLD_MAX", "HIGH_FIO2", 0, 10, 5, 1, 0]],
[["Pressure", " ", "HIGH_PRESSURE", "SET_THRESHOLD_MIN", "HIGH_PRESSURE"],["Inhale Pressure","","inspiratory_pressure","SET_TARGET_CURRENT","INSPIRATORY_PRESSURE", 10, 50, 17, 1, 0],["Pressure", " ", "HIGH_PRESSURE", "SET_THRESHOLD_MAX", "HIGH_PRESSURE"],["Pressure", " ", "HIGH_PRESSURE", "SET_THRESHOLD_MAX", "HIGH_PRESSURE"]],
[["Respiratory Rate", " ", "HIGH_RR", "SET_THRESHOLD_MIN", "HIGH_RR", -10, 0, -5, 0.1, 1],["Respiratory Rate","/min","respiratory_rate","SET_TARGET_CURRENT","RESPIRATORY_RATE", 10, 20, 15, 0.1, 1],["Respiratory Rate", " ", "HIGH_RR", "SET_THRESHOLD_MAX", "HIGH_RR", 0, 10, 5, 0.1, 1]],
[["VTE", " ", "HIGH_VTE", "SET_THRESHOLD_MIN", "HIGH_VTE", -10, 0, -5, 1, 0],["Inhale Volume", "", "volume", "SET_TARGET_CURRENT", "VOLUME", 200, 800, 400, 20, 0],["VTE", " ", "HIGH_VTE", "SET_THRESHOLD_MAX", "HIGH_VTE",0, 10, 5, 1, 0]],
......
......@@ -5,22 +5,22 @@
"button_background_disabled":[100, 100, 100],
"button_foreground_enabled":[200, 200, 200],
"button_foreground_disabled":[30, 30, 30],
"button_background_highlight":[30,93,248],
"button_foreground_highlight":[200,200,200],
"label_background":[0, 0, 0],
"label_foreground":[200, 200, 200],
"display_background":[200, 200, 200],
"display_foreground":[0, 0, 0],
"display_foreground_changed":[0, 200, 0],
"display_foreground_red":[200, 0, 0],
"plot_pressure":[0, 114, 178],
"plot_volume":[0, 158, 115],
"plot_flow":[240, 228, 66],
"plot_pressure_flow":[230, 159, 0],
"plot_flow_volume":[204, 121, 167],
"plot_volume_pressure":[86, 180, 233],
"highligh":[30,93,248],
"baby_blue":[144, 231, 211],
"red":[200, 0, 0],
"green":[0, 200, 0],
"pressure_plot":[0, 114, 178],
"volume_plot":[0, 158, 115],
"flow_plot":[240, 228, 66],
"pressure_flow_plot":[230, 159, 0],
"flow_volume_plot":[204, 121, 167],
"volume_pressure_plot":[86, 180, 233],
"red":[255, 0, 0],
"green":[0, 255, 0],
"baby-blue":[0, 0, 200]
"green":[0, 200, 0]
}
......@@ -7,8 +7,8 @@
["Exhale Trigger Sensitivity","","exhale_trigger_threshold","SET_TARGET_","EXHALE_TRIGGER_THRESHOLD", 0, 50, 25, 0.2, 1],
["Inhale Pressure","","inspiratory_pressure","SET_TARGET_","INSPIRATORY_PRESSURE", 10, 50, 17, 1, 0],
["Inhale Volume", "", "volume", "SET_TARGET_", "VOLUME", 200, 800, 400, 20, 0],
["Percentage O2", "", "fiO2_percent", "SET_TARGET_", "FIO2_PERCENT", 20, 100, 21, 1, 0]],
["Percentage O2", "", "fiO2_percent", "SET_TARGET_", "FIO2_PERCENT", 20, 100, 51, 0.1, 1]],
"radioSettings": ["Inhale Time", "IE Ratio"],
"enableDict":{"PC/AC":[1, 1,0, 1, 1, 0, 1, 0, 1], "PC/AC-PRVC":[1, 1,1, 0, 1, 0, 1, 1, 1], "PC-PSV":[1, 1,1, 0, 1, 0, 1, 0, 1], "CPAP":[1, 1,0, 1, 1, 0, 1, 0, 1]},
"mainPageSettings": ["Inhale Pressure", "Respiratory Rate", "Inhale Time", "IE Ratio", "Percentage O2" ]
"mainPageSettings": ["Inhale Pressure", "Respiratory Rate", "Inhale Time", "IE Ratio", "Percentage O2", "PEEP" ]
}
\ No newline at end of file
......@@ -30,6 +30,7 @@ class SetConfirmPopup(QtWidgets.QDialog):
"""Popup called when user wants to send new values to microcontroller.
This popup shows changes and asks for confirmation"""
# a signal for each handler, so the UI knows which values were updated
ExpertSend = QtCore.Signal()
ModeSend = QtCore.Signal()
PersonalSend = QtCore.Signal()
......@@ -41,6 +42,7 @@ class SetConfirmPopup(QtWidgets.QDialog):
self.NativeUI = NativeUI
self.handler = None
# list widget displays the changes to be sent to MCU in human readable way
self.listWidget = QtWidgets.QListWidget()
self.listWidget.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.listWidget.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
......@@ -61,18 +63,19 @@ class SetConfirmPopup(QtWidgets.QDialog):
vlayout.addLayout(buttonHLayout)
self.setLayout(vlayout)
# self.setAttribute(QtCore.Qt.WA_NoSystemBackground, True)
# self.setWindowOpacity(0.5)
def populatePopup(self, handlerWidget, messageList):
"""One popup is used for all the handlers. It is populated when called by a particular handler"""
self.handler = handlerWidget
self.clearPopup()
self.listWidget.clear()
if messageList == []:
messageList = ["no values were set"]
for item in messageList:
listItem = QtWidgets.QListWidgetItem(item)
listItem.setFlags(QtCore.Qt.NoItemFlags)
self.listWidget.addItem(listItem)
# adjust size according to list contents
self.listWidget.setFixedHeight(
self.listWidget.sizeHintForRow(0) * self.listWidget.count() + 10
)
......@@ -82,14 +85,10 @@ class SetConfirmPopup(QtWidgets.QDialog):
self.listWidget.update()
self.update()
def clearPopup(self):
self.listWidget.clear()
self.commandList = []
return 0
def ok_button_pressed(self):
"""Send commands when ok button is clicked"""
# self.parentTemplate.liveUpdating = True
"""Emit signal to connect with handler corresponding to editted values."""
if self.handler is None:
logging.error("Popup ok_button_pressed called before popupatePopup")
return 1
......@@ -114,6 +113,8 @@ class SetConfirmPopup(QtWidgets.QDialog):
class confirmWidget(QtWidgets.QWidget):
"""A widget displaying an individual command confirmation from the MCU. Is contained in confirmPopup"""
def __init__(self, NativeUI, confirmMessage, *args, **kwargs):
super(confirmWidget, self).__init__(*args, **kwargs)
self.hlayout = QtWidgets.QHBoxLayout()
......@@ -137,16 +138,18 @@ class confirmWidget(QtWidgets.QWidget):
self.setLayout(self.hlayout)
self.setFixedHeight(50)
# create timer to handle timeout
self.timer = QtCore.QTimer()
self.timer.setInterval(10000)
self.timer.timeout.connect(self.confirmTimeout)
self.timer.start()
def confirmTimeout(self):
"""Widget should expire after a defined time"""
self.parent().confirmDict.pop(
self.confirmMessage.replace("/", "_").replace("-", "_")
self.confirmMessage.replace("/", "_").replace("-", "_") # - and / are not used in dictionary keys
)
self.setParent(None)
self.setParent(None) # delete self
class confirmPopup(QtWidgets.QDialog):
......@@ -173,12 +176,11 @@ class confirmPopup(QtWidgets.QDialog):
) # no window title
self.timer = QtCore.QTimer()
self.timer.setInterval(500) # just faster than 60Hz
self.timer.timeout.connect(self.adjustSize)
self.timer.setInterval(500)
self.timer.timeout.connect(self.adjustSize) # container needs to adjust to a new number of confirmWidgets
self.timer.start()
def addConfirmation(self, confirmMessage):
print('adding confirmation')
"""Add a confirmation to the popup. Triggered when UI receives a confirmation from the microcontroller"""
self.confirmDict[confirmMessage] = confirmWidget(
self.NativeUI, confirmMessage
......@@ -187,8 +189,10 @@ class confirmPopup(QtWidgets.QDialog):
return 0
def location_on_window(self):
"""Places confirmWidgets at the top center of the screen"""
screen = QtWidgets.QDesktopWidget().screenGeometry()
# widget = self.geometry()
x = screen.width() - screen.width() / 2
y = 0 # screen.height() - widget.height()
self.move(x, y)
return 0
......@@ -23,6 +23,7 @@ class AbstractTypeValPopup(QtWidgets.QDialog):
"""Popup takes user input to put in spin box. """
okPressed = QtCore.Signal(str)
cancelPressed = QtCore.Signal()
correctPassword = QtCore.Signal()
def __init__(self, NativeUI, characterType, *args, **kwargs):
super().__init__(*args, **kwargs)
......@@ -32,6 +33,8 @@ class AbstractTypeValPopup(QtWidgets.QDialog):
grid = QtWidgets.QGridLayout()
grid.setSpacing(1)
#self.label_text, self.min, self.max, self.initVal, self.step, self.decPlaces = 'Enter Password', 0, 10000, 0, 0, 0
self.setStyleSheet("border-radius:4px; background-color:black")
self.characterType = characterType
self.label = QtWidgets.QLabel() # self.label_text)
......@@ -84,24 +87,17 @@ class AbstractTypeValPopup(QtWidgets.QDialog):
self.numberpad.numberPressed.connect(self.handle_alphapress)
hlayout.addWidget(self.lineEdit)
# grid.addWidget(self.lineEdit, 0, 0, 1, 2)
self.hlayout2 = QtWidgets.QHBoxLayout()
self.okButton = OkButtonWidget(NativeUI)
self.okButton.setEnabled(True)
self.okButton.pressed.connect(self.handle_ok_press)
self.hlayout2.addWidget(self.okButton)
# grid.addWidget(self.okButton, 1, 0)
self.cancelButton = CancelButtonWidget(NativeUI)
self.cancelButton.setEnabled(True)
self.hlayout2.addWidget(self.cancelButton)
# grid.addWidget(self.cancelButton, 1, 1)
vlayout = QtWidgets.QVBoxLayout()
vlayout.addWidget(self.label)
vlayout.addLayout(hlayout)
......@@ -112,6 +108,13 @@ class AbstractTypeValPopup(QtWidgets.QDialog):
self.setWindowFlags(
QtCore.Qt.FramelessWindowHint | QtCore.Qt.WindowStaysOnTopHint
) # no window title