gui¶
Design Requirements¶
Display Values
Value name, units, absolute range, recommended range, default range
VTE
FiO2
Humidity
Temperature
Plots
Controlled Values
PIP
PEEP
Inspiratory Time
Value Dependencies
UI Notes & Todo¶
Jonny add notes from helpful RT in discord!!!
Top status Bar
Start/stop button
Status indicator - a clock that increments with heartbeats, or some other visual indicator that things are alright
Status bar - most recent alarm or notification w/ means of clearing
Override to give 100% oxygen and silence all alarms
API
Two queues, input and output. Read from socket and put directly into queue.
Input, receive (timestamp, key, value) messages where key and value are names of variables and their values
Output, send same format
Menus
Trigger some testing/calibration routine
Log/alarm viewer
Wizard to set values?
save/load values
Alarms
Multiple levels
Silenced/reset
Logging
Sounds?
General
Reduce space given to waveforms
Clearer grouping & titling for display values & controls
Collapsible range setting
Ability to declare dependencies between values
Limits - one value’s range logically depends on another
Derived - one value is computed from another/others
Monitored values should have defaults, warning range, and absolute range
Two classes of monitored values – ones with limits and ones without. There seem to be lots and lots of observed values, but only some need limits. might want to make larger drawer of smaller displayed values that don’t need controls
Save/load parameters. Autosave, and autorestore if saved <5m ago, otherwise init from defaults.
Implement timed updates to plots to limit resource usage
Make class for setting values
Possible plots
Pressure vs. flow
flow vs volume
volume vs time
Performance
Cache drawText() calls in range selector by drawing to pixmap
Jonny Questions¶
Which alarm sounds to use?
Final final final breakdown on values and ranges plzzz
jonny todo¶
use loop_counter to check on controller advancement
implement single values list with properties ‘controllable’ vs not.
GUI Object Documentation¶
Classes
|
The Main GUI window. |
Functions
|
-
class
vent.gui.main.
Vent_Gui
(coordinator, update_period=0.1)[source]¶ The Main GUI window.
Only one instance can be created at a time. Uses
set_gui_instance()
to store a reference to itself. after initialization, use get_gui_instance to retrieve a reference.Attributes
see
gui.defaults.CONTROL
see
gui.defaults.SENSOR
see
gui.defaults.PLOTS
alarms_updated
(*args, **kwargs)PySide2.QtCore.Signal
emitted whenever alarms are updated.int([x]) -> integer
gui_closing
(*args, **kwargs)PySide2.QtCore.Signal
emitted when the GUI is closing.int([x]) -> integer
int([x]) -> integer
int([x]) -> integer
int([x]) -> integer
computed from
status_height+main_height
computed from
monitor_width+plot_width+control_width
Methods
__init__
(coordinator[, update_period])The Main GUI window.
alarm_state_changed
(state)closeEvent
(event)Emit
gui_closing
and close!handle_alarm
(alarm)handle_cleared_alarm
(alarm)on startup, set controls in coordinator to ensure init state is synchronized
init_ui
()Create the UI components for the ventilator screen
Connect Qt signals and slots
set_plot_duration
(dur)set_value
(new_value[, value_name])Set a control value with the
coordinator
update_value
(value_name, new_value)- param value_name
Name of key in
Vent_Gui.monitor
andVent_Gui.plots
to update
-
monitor
¶ Dictionary mapping
values.SENSOR
keys towidgets.Monitor_Value
objects- Type
-
controls
¶ Dictionary mapping
values.CONTROL
keys towidgets.Control
objects- Type
-
coordinator
¶ Some coordinator object that we use to communicate with the controller
-
control_module
¶ Reference to the control module, retrieved from coordinator
-
start_time
¶ Start time as returned by
time.time()
- Type
-
alarm_manager
¶ - Type
- Parameters
-
gui_closing
(*args, **kwargs) = <PySide2.QtCore.Signal object>¶ PySide2.QtCore.Signal
emitted when the GUI is closing.
-
alarms_updated
(*args, **kwargs) = <PySide2.QtCore.Signal object>¶ PySide2.QtCore.Signal
emitted whenever alarms are updated.Returns the result of
self.coordinator.get_active_alarms
, so will emit an empty dict if there are no active alarms.
-
MONITOR
= OrderedDict([(<ValueName.FIO2: 8>, <vent.common.values.Value object>), (<ValueName.TEMP: 9>, <vent.common.values.Value object>), (<ValueName.HUMIDITY: 10>, <vent.common.values.Value object>), (<ValueName.VTE: 11>, <vent.common.values.Value object>), (<ValueName.PRESSURE: 12>, <vent.common.values.Value object>), (<ValueName.IE_RATIO: 7>, <vent.common.values.Value object>)])¶ see
gui.defaults.SENSOR
-
CONTROL
= OrderedDict([(<ValueName.PIP: 1>, <vent.common.values.Value object>), (<ValueName.PIP_TIME: 2>, <vent.common.values.Value object>), (<ValueName.INSPIRATION_TIME_SEC: 6>, <vent.common.values.Value object>), (<ValueName.PEEP: 3>, <vent.common.values.Value object>), (<ValueName.PEEP_TIME: 4>, <vent.common.values.Value object>), (<ValueName.BREATHS_PER_MINUTE: 5>, <vent.common.values.Value object>)])¶ see
gui.defaults.CONTROL
-
PLOTS
= OrderedDict([(<ValueName.PRESSURE: 12>, {'name': 'Pressure', 'units': 'mmH2O', 'abs_range': (0, 70), 'safe_range': (0, 60), 'decimals': 1, 'default': None, 'color': '#FF6319'}), (<ValueName.TEMP: 9>, {'name': 'Temp', 'units': '°C', 'abs_range': (35, 40), 'safe_range': (36, 39), 'decimals': 1, 'default': None, 'color': '#EE352E'}), (<ValueName.HUMIDITY: 10>, {'name': 'Humidity', 'units': '%', 'abs_range': (0, 100), 'safe_range': (70, 100), 'decimals': 1, 'default': None, 'color': '#0039A6'})])¶ see
gui.defaults.PLOTS
-
monitor_width
= 2¶
-
plot_width
= 4¶
-
control_width
= 2¶
-
total_width
= 8¶ computed from
monitor_width+plot_width+control_width
-
status_height
= 1¶
-
main_height
= 5¶
-
total_height
= 6¶ computed from
status_height+main_height
-
__init__
(coordinator, update_period=0.1)[source]¶ The Main GUI window.
Only one instance can be created at a time. Uses
set_gui_instance()
to store a reference to itself. after initialization, use get_gui_instance to retrieve a reference.-
monitor
¶ Dictionary mapping
values.SENSOR
keys towidgets.Monitor_Value
objects- Type
-
controls
¶ Dictionary mapping
values.CONTROL
keys towidgets.Control
objects- Type
-
coordinator
¶ Some coordinator object that we use to communicate with the controller
-
control_module
¶ Reference to the control module, retrieved from coordinator
-
start_time
¶ Start time as returned by
time.time()
- Type
-
alarm_manager
¶ - Type
-
-
property
update_period
¶
-
init_controls
()[source]¶ on startup, set controls in coordinator to ensure init state is synchronized
-
set_value
(new_value, value_name=None)[source]¶ Set a control value with the
coordinator
- Parameters
new_value (float) – Som
-
update_value
(value_name, new_value)[source]¶ - Parameters
value_name (str) – Name of key in
Vent_Gui.monitor
andVent_Gui.plots
to update
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
property
alarm_state
¶
-
closeEvent
(event)[source]¶ Emit
gui_closing
and close!
Control¶
Classes
|
-
class
vent.gui.widgets.control.
Control
(value)[source]¶ Methods
init_ui
()toggle_control
(state)update_value
(new_value)-
value_changed
(*args, **kwargs) = <PySide2.QtCore.Signal object>¶
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
Monitor¶
Classes
|
|
-
class
vent.gui.widgets.monitor.
Monitor
(value, update_period=0.5, enum_name=None)[source]¶ - Parameters
value (
Value
) –update_period (float) – update period of monitor in s
Methods
__init__
(value[, update_period, enum_name])- param value
_limits_changed
(val)check_alarm
([value])init_ui
()set_alarm
(alarm)Simple wrapper to set alarm state from a qt signal
toggle_control
(state)update_boxes
(new_values)update_limits
(new_limits)update_value
(new_value)Attributes
-
alarm
(*args, **kwargs) = <PySide2.QtCore.Signal object>¶
-
limits_changed
(*args, **kwargs) = <PySide2.QtCore.Signal object>¶
-
__init__
(value, update_period=0.5, enum_name=None)[source]¶ - Parameters
value (
Value
) –update_period (float) – update period of monitor in s
-
property
alarm_state
¶
-
set_alarm
(alarm)[source]¶ Simple wrapper to set alarm state from a qt signal
- Parameters
alarm (bool) – Whether to set as alarm state or not
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
Plot¶
Data
Update frequency of |
|
A |
Classes
|
When initializing PlotWidget, parent and background are passed to |
-
class
vent.gui.widgets.plot.
Plot
(name, buffer_size=4092, plot_duration=5, abs_range=None, safe_range=None, color=None, units='', **kwargs)[source]¶ When initializing PlotWidget, parent and background are passed to
GraphicsWidget.__init__()
and all others are passed toPlotItem.__init__()
.Methods
_safe_limits_changed
(val)set_duration
(dur)set_safe_limits
(limits)update_value
(new_value)new_value: (timestamp from time.time(), value)
-
limits_changed
(*args, **kwargs) = <PySide2.QtCore.Signal object>¶
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
Status Bar¶
Classes
|
|
|
-
class
vent.gui.widgets.status_bar.
Status_Bar
[source]¶ Start/stop button
- Status indicator - a clock that increments with heartbeats,
or some other visual indicator that things are alright
Status bar - most recent alarm or notification w/ means of clearing
Override to give 100% oxygen and silence all alarms
Methods
init_ui
()-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
class
vent.gui.widgets.status_bar.
Message_Display
[source]¶ Attributes
Methods
draw_state
([state])init_ui
()update_message
(alarm)- param alarm
-
message_cleared
(*args, **kwargs) = <PySide2.QtCore.Signal object>¶
-
level_changed
(*args, **kwargs) = <PySide2.QtCore.Signal object>¶
-
property
alarm_level
¶
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
class
vent.gui.widgets.status_bar.
HeartBeat
(update_interval=100, timeout_dur=5000)[source]¶ - Parameters
Methods
__init__
([update_interval, timeout_dur])- param update_interval
How often to do the heartbeat, in ms
Called every (update_interval) milliseconds to set the text of the timer.
beatheart
(heartbeat_time)init_ui
()set_indicator
([state])start_timer
([update_interval])- param update_interval
How often (in ms) the timer should be updated.
you can read the sign ya punk
-
timeout
(*args, **kwargs) = <PySide2.QtCore.Signal object>¶
-
heartbeat
(*args, **kwargs) = <PySide2.QtCore.Signal object>¶
-
start_timer
(update_interval=None)[source]¶ - Parameters
update_interval (float) – How often (in ms) the timer should be updated.
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
Components¶
Classes
|
Slider capable of representing floats |
|
Editable label |
Custom key press handler |
|
|
with respct to https://stackoverflow.com/a/51057516 |
|
Slider with two handles that sets a range |
-
class
vent.gui.widgets.components.
DoubleSlider
(decimals=1, *args, **kargs)[source]¶ Slider capable of representing floats
Ripped off from and https://stackoverflow.com/a/50300848 ,
Thank you!!!
Methods
_maximum
()_minimum
()maximum
(self)minimum
(self)setDecimals
(decimals)setMaximum
(self, arg__1)setMinimum
(self, arg__1)setSingleStep
(self, arg__1)setValue
(self, arg__1)singleStep
(self)value
(self)-
doubleValueChanged
(*args, **kwargs) = <PySide2.QtCore.Signal object>¶
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
vent.gui.widgets.components.
RangeSlider
(abs_range, safe_range, decimals=1, *args, **kwargs)[source]¶ Slider with two handles that sets a range
- Parameters
Methods
__pick
(pt)__init__
(abs_range, safe_range[, decimals])Slider with two handles that sets a range
Generate the text labels for the slider.
mouseMoveEvent
(self, ev)mousePressEvent
(self, ev)paintEvent
(self, ev)resizeEvent
(self, event)setHigh
(high)setLow
(low)setValue
(value)- param value
(low, high) to set
value
(self)Attributes
valueChanged
(*args, **kwargs)(tuple): (low, high) set range of floats
-
valueChanged
(*args, **kwargs) = <PySide2.QtCore.Signal object>¶ (low, high) set range of floats
- Type
(tuple)
-
__init__
(abs_range, safe_range, decimals=1, *args, **kwargs)[source]¶ Slider with two handles that sets a range
-
property
low
¶
-
property
high
¶
-
generate_labels
()[source]¶ Generate the text labels for the slider.
Called on init and on resizeEvent
-
__pick
(pt)¶
-
__pixelPosToRangeValue
(pos)¶
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
class
vent.gui.widgets.components.
KeyPressHandler
[source]¶ Custom key press handler https://gist.github.com/mfessenden/baa2b87b8addb0b60e54a11c1da48046
Methods
eventFilter
(self, watched, event)-
escapePressed
(*args, **kwargs) = <PySide2.QtCore.Signal object>¶
-
returnPressed
(*args, **kwargs) = <PySide2.QtCore.Signal object>¶
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
vent.gui.widgets.components.
EditableLabel
(parent=None, **kwargs)[source]¶ Editable label https://gist.github.com/mfessenden/baa2b87b8addb0b60e54a11c1da48046
Methods
Escape event handler
labelPressedEvent
(event)Set editable if the left mouse button is clicked
Indicates the widget text has been updated
Return/enter event handler
Action to make the widget editable
setText
(text)Standard QLabel text setter
text
()Standard QLabel text getter
-
textChanged
(*args, **kwargs) = <PySide2.QtCore.Signal object>¶
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
-
class
vent.gui.widgets.components.
QHLine
(parent=None, color='#FFFFFF')[source]¶ with respct to https://stackoverflow.com/a/51057516
Methods
setColor
(color)-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-
GUI Stylesheets¶
Data
(float): inter-update interval (seconds) for |
Functions
|
Apply Dark Theme to the Qt application instance. |
-
vent.gui.styles.
MONITOR_UPDATE_INTERVAL
= 0.5¶ inter-update interval (seconds) for
Monitor
- Type
(float)
-
vent.gui.styles.
set_dark_palette
(app)[source]¶ Apply Dark Theme to the Qt application instance.
- borrowed from https://github.com/gmarull/qtmodern/blob/master/qtmodern/styles.py
- Args:
app (QApplication): QApplication instance.
GUI Alarm Manager¶
Classes
Functions
-
class
vent.gui.alarm_manager.
AlarmManager
[source]¶ Methods
monitor_alarm
(alarm)Parse a tentative alarm from a monitor – we should have already gotten an alarm from the controller, so this largely serves as a double check.
parse_message
(alarm)If an alarm doesn’t have a
message
attr, make one for it.update_alarms
(alarms)-
new_alarm
(*args, **kwargs) = <PySide2.QtCore.Signal object>¶
-
monitor_alarm
(alarm)[source]¶ Parse a tentative alarm from a monitor – we should have already gotten an alarm from the controller, so this largely serves as a double check.
Doesn’t use the
Alarm
class because creating a new alarm increments the counter.- Parameters
alarm (tuple) – (monitor_name, monitor_value, timestamp)
-
staticMetaObject
= <PySide2.QtCore.QMetaObject object>¶
-