Commit 7c9e20ea authored by Benjamin Mummery's avatar Benjamin Mummery 💻

merged localisation POC into ui_dev

parent fe8049f4
......@@ -12,13 +12,13 @@ __pycache__
*.csv
raspberry-dataserver/foo
env/
BM_SCRATCH
.cache
.pylintrc
.pre-commit-config.yaml
.env
ansible/playbooks/hosts
.idea
scratch_*
# python virtual env created using ansible
.hev_env
......@@ -167,4 +167,3 @@ dmypy.json
.prof
# End of https://www.toptal.com/developers/gitignore/api/python
......@@ -9,6 +9,9 @@ repos:
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- id: check-json
# - id: pretty-format-json
- id: requirements-txt-fixer
- repo: https://github.com/psf/black
rev: 19.3b0
hooks:
......
......@@ -52,52 +52,47 @@ class NativeUI(HEVClient, QMainWindow):
super(NativeUI, self).__init__(*args, **kwargs)
self.setWindowTitle("HEV NativeUI")
config_path = self.__find_configs()
# self.setFixedSize(1920, 1080)
self.modeList = ["PC/AC", "PC/AC-PRVC", "PC-PSV", "CPAP"]
self.currentMode = self.modeList[0]
self.colors = { # colorblind friendly ref: https://i.stack.imgur.com/zX6EV.png
"page_background": QColor.fromRgb(30, 30, 30),
"page_foreground": QColor.fromRgb(200, 200, 200),
"button_background_enabled": QColor.fromRgb(50, 50, 50),
"button_background_disabled": QColor.fromRgb(100, 100, 100),
"button_foreground_enabled": QColor.fromRgb(200, 200, 200),
"button_foreground_disabled": QColor.fromRgb(30, 30, 30),
"label_background": QColor.fromRgb(0, 0, 0),
"label_foreground": QColor.fromRgb(200, 200, 200),
"display_background": QColor.fromRgb(200, 200, 200),
"display_foreground": QColor.fromRgb(0, 0, 0),
"baby_blue": QColor.fromRgb(144, 231, 211),
"red": QColor.fromRgb(200, 0, 0),
"green": QColor.fromRgb(0, 200, 0),
"pressure_plot": QColor.fromRgb(0, 114, 178),
"volume_plot": QColor.fromRgb(0, 158, 115),
"flow_plot": QColor.fromRgb(240, 228, 66),
"pressure_flow_plot": QColor.fromRgb(230, 159, 0),
"flow_volume_plot": QColor.fromRgb(204, 121, 167),
"volume_pressure_plot": QColor.fromRgb(86, 180, 233),
"red": QColor.fromRgb(255, 0, 0),
"green": QColor.fromRgb(0, 255, 0),
"baby-blue": QColor.fromRgb(0, 0, 200),
}
self.localisation_files = ["text_english.json", "text_portuguese.json"]
self.localisation_files = [
os.path.join(config_path, file) for file in self.localisation_files
]
# Import settings from config files
with open(os.path.join(config_path, "colors.json")) as f:
# colorblind friendly ref: https://i.stack.imgur.com/zX6EV.png
self.colors = json.load(f)
with open(os.path.join(config_path, "text_english.json")) as f:
self.text = json.load(f)
# convert colours to a PySide2-readble form
for key in self.colors:
self.colors[key] = QColor.fromRgb(*self.colors[key])
self.text_font = QFont("Sans Serif", 20)
self.value_font = QFont("Sans Serif", 40)
self.text_size = "20pt" # TODO: remove in favour of self.text_font
self.text = {
"plot_axis_label_pressure": "Pressure [cmH<sub>2</sub>O]",
"plot_axis_label_flow": "Flow [L/min]",
"plot_axis_label_volume": "Volume [mL]",
"plot_axis_label_time": "Time [s]",
"plot_line_label_pressure": "Airway Pressure",
"plot_line_label_flow": "Flow",
"plot_line_label_volume": "Volume",
"plot_line_label_pressure_flow": "Airway Pressure - Flow",
"plot_line_label_flow_volume": "Flow - Volume",
"plot_line_label_volume_pressure": "Volume - Airway Pressure",
"layout_label_measurements": "Measurements",
"button_label_main_normal": "Normal",
"button_label_main_detailed": "Detailed",
}
# self.text = {
# "plot_axis_label_pressure": "Pressure [cmH<sub>2</sub>O]",
# "plot_axis_label_flow": "Flow [L/min]",
# "plot_axis_label_volume": "Volume [mL]",
# "plot_axis_label_time": "Time [s]",
# "plot_line_label_pressure": "Airway Pressure",
# "plot_line_label_flow": "Flow",
# "plot_line_label_volume": "Volume",
# "plot_line_label_pressure_flow": "Airway Pressure - Flow",
# "plot_line_label_flow_volume": "Flow - Volume",
# "plot_line_label_volume_pressure": "Volume - Airway Pressure",
# "layout_label_measurements": "Measurements",
# "button_label_main_normal": "Normal",
# "button_label_main_detailed": "Detailed",
# }
self.icons = {
"button_main_page": "user-md-solid",
"button_alarms_page": "exclamation-triangle-solid",
......@@ -250,6 +245,11 @@ class NativeUI(HEVClient, QMainWindow):
self.MeasurementSignal.connect(self.widgets.normal_measurements.update_value)
self.MeasurementSignal.connect(self.widgets.detailed_measurements.update_value)
# Localisation needs to update widgets
self.widgets.localisation_button.SetLocalisation.connect(
self.widgets.normal_measurements.localise_text
)
return 0
def __emit_plots_signal(self) -> int:
......@@ -473,7 +473,7 @@ class NativeUI(HEVClient, QMainWindow):
def __find_icons(self, iconext: str) -> str:
"""
Locate the icons firectory and return its path.
Locate the icons directory and return its path.
Assumes that the cwd is in a git repo, and that the path of the icons folder
relative to the root of the repo is "hev-display/assets/png/".
......@@ -488,6 +488,23 @@ class NativeUI(HEVClient, QMainWindow):
return icondir
def __find_configs(self) -> str:
"""
Locate the config files directory and return its path.
Assumes that the cwd is in a git repo, and that the path of the icons folder
relative to the root of the repo is "NativeUI/configs".
"""
# Find the root of the git repo
rootdir = git.Repo(os.getcwd(), search_parent_directories=True).git.rev_parse(
"--show-toplevel"
)
configdir = os.path.join(rootdir, "NativeUI", "configs")
if not os.path.isdir(configdir):
raise FileNotFoundError("Could not find icon directory at %s" % configdir)
return configdir
# from PySide2.QtQml import QQmlApplicationEngine
......
{
"language_name": "English",
"plot_axis_label_pressure": "Pressure [cmH<sub>2</sub>O]",
"plot_axis_label_flow": "Flow [L/min]",
"plot_axis_label_volume": "Volume [mL]",
"plot_axis_label_time": "Time [s]",
"plot_line_label_pressure": "Airway Pressure",
"plot_line_label_flow": "Flow",
"plot_line_label_volume": "Volume",
"plot_line_label_pressure_flow": "Airway Pressure - Flow",
"plot_line_label_flow_volume": "Flow - Volume",
"plot_line_label_volume_pressure": "Volume - Airway Pressure",
"layout_label_measurements": "Measurements",
"button_label_main_normal": "Normal",
"button_label_main_detailed": "Detailed",
"ui_window_title": "HEV NativeUI",
"measurement_label_plateau_pressure": "P<sub>PLATEAU</sub> [cmH<sub>2</sub>O]",
"measurement_label_respiratory_rate": "RR",
"measurement_label_fio2_percent": "FIO<sub>2</sub> [%]",
"measurement_label_exhaled_tidal_volume": "VTE [mL]",
"measurement_label_exhaled_minute_volume": "MVE [<sup>L</sup>/<sub>min</sub>]",
"measurement_label_peep": "PEEP [cmH<sub>2</sub>O]",
"measurement_label_inhale_exhale_ratio": "I:E",
"measurement_label_mean_airway_pressure": "P<sub>MEAN</sub> [cmH<sub>2</sub>O]",
"measurement_label_inhaled_tidal_volume": "VTI [mL]",
"measurement_label_inhaled_minute_volume": "MVI [L/min]",
"measurement_label_peak_inspiratory_pressure": "P<sub>PEAK</sub> [cmH<sub>2</sub>O]"
}
{
"language_name": "Português",
"plot_axis_label_pressure": "Pressure [cmH<sub>2</sub>O]",
"plot_axis_label_flow": "Flow [L/min]",
"plot_axis_label_volume": "Volume [mL]",
"plot_axis_label_time": "Time [s]",
"plot_line_label_pressure": "Airway Pressure",
"plot_line_label_flow": "Flow",
"plot_line_label_volume": "Volume",
"plot_line_label_pressure_flow": "Airway Pressure - Flow",
"plot_line_label_flow_volume": "Flow - Volume",
"plot_line_label_volume_pressure": "Volume - Airway Pressure",
"layout_label_measurements": "Measurements",
"button_label_main_normal": "Normal",
"button_label_main_detailed": "Detailed",
"ui_window_title": "HEV NativeUI",
"measurement_label_plateau_pressure": "TRANSLATE",
"measurement_label_respiratory_rate": "TRANSLATE",
"measurement_label_fio2_percent": "TRANSLATE",
"measurement_label_exhaled_tidal_volume": "TRANSLATE",
"measurement_label_exhaled_minute_volume": "TRANSLATE",
"measurement_label_peep": "PEEP [cmH<sub>2</sub>O]",
"measurement_label_inhale_exhale_ratio": "I:E",
"measurement_label_mean_airway_pressure": "P<sub>MEAN</sub> [cmH<sub>2</sub>O]",
"measurement_label_inhaled_tidal_volume": "VTI [mL]",
"measurement_label_inhaled_minute_volume": "MVI [L/min]",
"measurement_label_peak_inspiratory_pressure": "P<sub>PEAK</sub> [cmH<sub>2</sub>O]"
}
......@@ -100,7 +100,8 @@ class Layout:
self.layout_top_bar(
[
self.widgets.tab_modeswitch,
self.widgets.tab_personal,
self.widgets.personal_display,
self.widgets.localisation_button,
self.widgets.battery_display,
]
)
......
......@@ -13,6 +13,7 @@ __maintainer__ = "Benjamin Mummery"
__email__ = "benjamin.mummery@stfc.ac.uk"
__status__ = "Prototype"
from widget_library.localisation_button_widget import LocalisationButtonWidget
from alarm_widgets.tab_alarm_table import TabAlarmTable
from alarm_widgets.tab_alarms import TabAlarm
from alarm_widgets.tab_clinical import TabClinical
......@@ -56,7 +57,8 @@ class Widgets:
# Top bar widgets
self.tab_modeswitch = TabModeswitchButton(NativeUI)
self.battery_display = BatteryDisplayWidget(NativeUI)
self.tab_personal = PersonalDisplayWidget(NativeUI)
self.personal_display = PersonalDisplayWidget(NativeUI)
self.localisation_button = LocalisationButtonWidget(NativeUI.localisation_files)
# Left Bar widgets
self.page_buttons = PageButtonsWidget(NativeUI)
......
#!/usr/bin/.hev_env python3
"""
localisation_button_widget.py
Part of NativeUI. Defines the LocalisationButtonWidget class to allow the user to set
the language for the interface.
"""
__author__ = "Benjamin Mummery"
__credits__ = ["Benjamin Mummery", "Dónal Murray", "Tim Powell", "Tiago Sarmento"]
__license__ = "GPL"
__version__ = "0.0.1"
__maintainer__ = "Benjamin Mummery"
__email__ = "benjamin.mummery@stfc.ac.uk"
__status__ = "Development"
from PySide2 import QtWidgets
import json
import os
from PySide2.QtCore import Signal
class LocalisationButtonWidget(QtWidgets.QPushButton):
"""
TODO BM: add set_size and setFont
"""
SetLocalisation = Signal(dict)
def __init__(self, localisation_config_file_paths: list, *args, **kwargs):
super().__init__(*args, **kwargs)
self.__localisation_dict: dict = {}
self.__localisation_files_list: list = localisation_config_file_paths
self.__current_localisation_index: int = -1
self.set_localisation(0)
self.pressed.connect(self.on_press)
def on_press(self) -> int:
"""
When the button is pressed, update the localisation.
"""
index = self.__current_localisation_index + 1
if index >= len(self.__localisation_files_list):
index = 0
self.set_localisation(index)
return 0
def set_localisation(self, index: int) -> int:
"""
Set the current localisation parameters to those of the the specified index,
then emit the SetLocalisation signal to propogate that change.
"""
if index == self.__current_localisation_index:
return 0
self.__current_localisation_index = index
self.__import_localisation_config()
self.setText(self.__localisation_dict["language_name"])
self.SetLocalisation.emit(self.__localisation_dict)
return 0
def __import_localisation_config(self) -> int:
"""
Read in the current configuration
"""
with open(
self.__localisation_files_list[self.__current_localisation_index]
) as infile:
self.__localisation_dict = json.load(infile)
return 0
......@@ -37,7 +37,7 @@ class MeasurementsBlockWidget(QtWidgets.QWidget):
layout = QtWidgets.QGridLayout(self)
# Create "Measurements" Title
self.title_label = QtWidgets.QLabel(NativeUI.text["layout_label_measurements"])
self.title_label = QtWidgets.QLabel()
self.title_label.setStyleSheet(
# "font-size:" + NativeUI.text_size + ";"
"color:" + NativeUI.colors["page_foreground"].name() + ";"
......@@ -55,7 +55,7 @@ class MeasurementsBlockWidget(QtWidgets.QWidget):
self.widget_list.append(
MeasurementWidget(
NativeUI,
measurement[0], # Label
measurement[0], # Label key
measurement[2], # Keydir
measurement[1], # Key
measurement[3], # Format
......@@ -65,7 +65,7 @@ class MeasurementsBlockWidget(QtWidgets.QWidget):
self.widget_list.append(
MeasurementWidget(
NativeUI,
measurement[0], # Label
measurement[0], # Label key
measurement[2], # Keydir
measurement[1], # Key
)
......@@ -95,6 +95,7 @@ class MeasurementsBlockWidget(QtWidgets.QWidget):
layout.setAlignment(QtCore.Qt.AlignHCenter)
self.setLayout(layout)
self.localise_text(NativeUI.text)
def set_size(
self, x: int, y: int, spacing: int = 10, widget_size_ratio: float = 2.5
......@@ -158,6 +159,20 @@ class MeasurementsBlockWidget(QtWidgets.QWidget):
widget.value_display.setFont(font)
return 0
@QtCore.Slot(dict)
def localise_text(self, text: dict) -> int:
"""
Update the text displayed on the title and all measurement labels.
"""
# set the text for the title label
self.title_label.setText(text["layout_label_measurements"])
# Set the text for each of the measurement widgets
for widget in self.widget_list:
widget.localise_text(text)
return 0
@QtCore.Slot(dict, dict)
def update_value(self, cycle: dict, readback: dict) -> int:
for widget in self.widget_list:
......@@ -187,7 +202,7 @@ class MeasurementWidget(QtWidgets.QWidget):
def __init__(
self,
NativeUI,
label: str,
label_key: str,
keydir: str,
key: str,
format: str = "{:.1f}",
......@@ -197,6 +212,7 @@ class MeasurementWidget(QtWidgets.QWidget):
super(MeasurementWidget, self).__init__(*args, **kwargs)
self.NativeUI = NativeUI
self.label_key = label_key
self.keydir = keydir
self.key = key
self.format = format
......@@ -204,7 +220,7 @@ class MeasurementWidget(QtWidgets.QWidget):
# Layout and widgets
layout = QtWidgets.QVBoxLayout()
self.name_display = QtWidgets.QLabel(label)
self.name_display = QtWidgets.QLabel()
self.value_display = QtWidgets.QLabel()
layout.addWidget(self.name_display)
......@@ -261,11 +277,24 @@ class MeasurementWidget(QtWidgets.QWidget):
return self.format.format(number)
def set_size(self, x: int, y: int) -> int:
"""
Set the size of the widget to the specified x and y values in pixels.
The overall widget size is fixed to x by y pixels. Name and value displays have
width x, and height y/3 and 2y/3 respectively.
"""
self.setFixedSize(x, y)
self.name_display.setFixedSize(x, int(y / 3))
self.value_display.setFixedSize(x, int(2 * y / 3))
return 0
def localise_text(self, text: dict) -> int:
"""
Set the name display text the relevent entry in the provided dictionary.
"""
self.name_display.setText(text[self.label_key])
return 0
class NormalMeasurementsBlockWidget(MeasurementsBlockWidget):
"""
......@@ -276,17 +305,17 @@ class NormalMeasurementsBlockWidget(MeasurementsBlockWidget):
def __init__(self, NativeUI, *args, **kwargs):
measurements = [
("P<sub>PLATEAU</sub> [cmH<sub>2</sub>O]", "plateau_pressure", "cycle"),
("RR", "respiratory_rate", "cycle"),
("FIO<sub>2</sub> [%]", "fiO2_percent", "cycle"),
("VTE [mL]", "exhaled_tidal_volume", "cycle"),
("measurement_label_plateau_pressure", "plateau_pressure", "cycle"),
("measurement_label_respiratory_rate", "respiratory_rate", "cycle"),
("measurement_label_fio2_percent", "fiO2_percent", "cycle"),
("measurement_label_exhaled_tidal_volume", "exhaled_tidal_volume", "cycle"),
(
"MVE [<sup>L</sup>/<sub>min</sub>]",
"measurement_label_exhaled_minute_volume",
"exhaled_minute_volume",
"cycle",
"{:.0f}",
),
("PEEP [cmH<sub>2</sub>O]", "peep", "readback"),
("measurement_label_peep", "peep", "readback"),
]
super().__init__(
......@@ -303,20 +332,34 @@ class ExpertMeasurementsBloackWidget(MeasurementsBlockWidget):
def __init__(self, NativeUI, *args, **kwargs):
measurements = [
("FIO<sub>2</sub> [%]", "fiO2_percent", "cycle"),
("I:E", "inhale_exhale_ratio", "readback", "ratio"),
("measurement_label_fio2_percent", "fiO2_percent", "cycle"),
(
"measurement_label_inhale_exhale_ratio",
"inhale_exhale_ratio",
"readback",
"ratio",
),
(
"P<sub>PEAK</sub> [cmH<sub>2</sub>O]",
"measurement_label_peak_inspiratory_pressure",
"peak_inspiratory_pressure",
"cycle",
),
("P<sub>PLATEAU</sub> [cmH<sub>2</sub>O]", "plateau_pressure", "cycle"),
("P<sub>MEAN</sub> [cmH<sub>2</sub>O]", "mean_airway_pressure", "cycle"),
("PEEP [cmH<sub>2</sub>O]", "peep", "readback"),
("VTI [mL]", "inhaled_tidal_volume", "cycle"),
("VTE [mL]", "exhaled_tidal_volume", "cycle"),
("MVI [L/min]", "inhaled_minute_volume", "cycle"),
("MVE [L/min]", "exhaled_minute_volume", "cycle", "{:.0f}"),
("measurement_label_plateau_pressure", "plateau_pressure", "cycle"),
("measurement_label_mean_airway_pressure", "mean_airway_pressure", "cycle"),
("measurement_label_peep", "peep", "readback"),
("measurement_label_inhaled_tidal_volume", "inhaled_tidal_volume", "cycle"),
("measurement_label_exhaled_tidal_volume", "exhaled_tidal_volume", "cycle"),
(
"measurement_label_inhaled_minute_volume",
"inhaled_minute_volume",
"cycle",
),
(
"measurement_label_exhaled_minute_volume",
"exhaled_minute_volume",
"cycle",
"{:.0f}",
),
]
super().__init__(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment