Source code for prsctrl_gui.measurement.viewer
""":class:`PrsLiveDataWidget` shows data during measurement."""
from pyqtgraph.examples.MultiDataPlot import lay
from prsctrl.data import PrsData
from ..gui.widgets.data import PrsDataWidget
from PyQt6.QtWidgets import QHBoxLayout, QLabel, QTabWidget, QWidget, QVBoxLayout, QLayoutItem
import logging
log = logging.getLogger(__name__)
[docs]
class PrsLiveDataWidget(QWidget):
"""Widget that can show multiple :class:`.PrsDataWidget`s and status messages.
This class differs from :class:`.PrsLiveDataWidget` in that its data source is not a :class:`.PrsData` instance,
but rather a numpy array from :meth:`.PrsData.get_spectrum_data` (sent by :class:`prsctrl.measurement.MeasurementHandler`).
It can show multiple datasets at once, with only one set of column switches.
"""
[docs]
def __init__(self, **kwargs):
QWidget.__init__(self, **kwargs)
self.l_main = QHBoxLayout()
self.setLayout(self.l_main)
# self.w_tabs = QTabWidget(self)
self.mode_datas: dict[str, PrsDataWidget] = {}
self.mode_labels: dict[str, QLabel] = {}
self.set_modes([])
self.raise_exceptions = True
[docs]
def _remove_widgets(self):
"""Empty the widget"""
while self.l_main.count():
item: QLayoutItem = self.l_main.takeAt(0)
widget = item.widget()
if widget:
widget.setParent(None)
widget.deleteLater()
layout = item.layout()
if layout:
layout.setParent(None)
layout.deleteLater()
self.l_main.removeItem(item)
del item
[docs]
def add_data(self, mode: str, wl: str|float|int, data: dict):
"""Add raw data to the PrsDataWidget's data container"""
if not isinstance(data, dict):
raise TypeError(f"Argument type for data must be dict, but is '{type(data)}'.")
try:
if mode not in self.mode_datas:
raise KeyError(f"Invalid mode '{mode}': Modes are {list(self.mode_datas.keys())}")
self.mode_datas[mode]._data[wl] = data
except Exception as e:
log.error(f"Error updating plot '{mode}': {type(e)}: {e}")
if self.raise_exceptions:
raise e
[docs]
def update_plot(self, mode: str):
"""Update the plot lines for the given mode.
Call this function after a new measurement point was added to the data.
:param mode: mode key of the plot to update
:param raise_exceptions: Whether to raise occuring exceptions. Exceptions are always logged.
"""
try:
if mode not in self.mode_datas:
raise KeyError(f"Invalid mode '{mode}': Modes are {list(self.mode_datas.keys())}")
self.mode_datas[mode].update_plots()
except Exception as e:
log.error(f"Error updating plot '{mode}': {type(e)}: {e}")
if self.raise_exceptions:
raise e
[docs]
def set_text(self, mode: str, text: str):
"""Set the status text for the given mode.
:param mode: mode key of the text to update
:param text: text to set
:param raise_exceptions: Whether to raise occuring exceptions. Exceptions are always logged.
"""
try:
if mode not in self.mode_labels:
raise KeyError(f"Invalid mode '{mode}': Modes are {list(self.mode_labels.keys())}")
self.mode_labels[mode].setText(text)
except Exception as e:
log.error(f"Error updating label '{mode}': {type(e)}: {e}")
if self.raise_exceptions:
raise e
[docs]
def set_modes(self, modes: list[str]):
"""Set the data modes that should be shown.
:param modes: list of mode keys
"""
log.debug(f"Setting mode datas {modes}")
self._remove_widgets()
self.mode_datas = {}
self.mode_labels = {}
for k in modes:
data = PrsData(data_path="", file_mode="", exp_mode=k)
w = PrsDataWidget(data)
l_mode = QVBoxLayout()
self.mode_datas[k] = w
self.mode_labels[k] = QLabel(f"Mode: {k}")
l_mode.addWidget(self.mode_labels[k])
l_mode.addWidget(self.mode_datas[k], 1)
self.l_main.addLayout(l_mode)
if len(self.mode_datas) == 0:
label = QLabel(self.tr("No measurement running."))
self.l_main.addWidget(label)