mirror of
https://github.com/bec-project/bec_widgets.git
synced 2025-07-13 19:21:50 +02:00
refactor(multi_waveform_widget): BECMultiWaveformWidget removed
This commit is contained in:
@ -18,7 +18,6 @@ class Widgets(str, enum.Enum):
|
||||
AbortButton = "AbortButton"
|
||||
BECColorMapWidget = "BECColorMapWidget"
|
||||
BECDockArea = "BECDockArea"
|
||||
BECMultiWaveformWidget = "BECMultiWaveformWidget"
|
||||
BECProgressBar = "BECProgressBar"
|
||||
BECQueue = "BECQueue"
|
||||
BECStatusBox = "BECStatusBox"
|
||||
@ -1547,205 +1546,6 @@ class BECMultiWaveform(RPCBase):
|
||||
"""
|
||||
|
||||
|
||||
class BECMultiWaveformWidget(RPCBase):
|
||||
@property
|
||||
@rpc_call
|
||||
def curves(self) -> list[pyqtgraph.graphicsItems.PlotDataItem.PlotDataItem]:
|
||||
"""
|
||||
Get the curves of the plot widget as a list
|
||||
Returns:
|
||||
list: List of curves.
|
||||
"""
|
||||
|
||||
@rpc_call
|
||||
def set_monitor(self, monitor: str) -> None:
|
||||
"""
|
||||
Set the monitor of the plot widget.
|
||||
|
||||
Args:
|
||||
monitor(str): The monitor to set.
|
||||
"""
|
||||
|
||||
@rpc_call
|
||||
def set_curve_highlight(self, index: int) -> None:
|
||||
"""
|
||||
Set the curve highlight of the plot widget by index
|
||||
|
||||
Args:
|
||||
index(int): The index of the curve to highlight.
|
||||
"""
|
||||
|
||||
@rpc_call
|
||||
def set_opacity(self, opacity: int) -> None:
|
||||
"""
|
||||
Set the opacity of the plot widget.
|
||||
|
||||
Args:
|
||||
opacity(int): The opacity to set.
|
||||
"""
|
||||
|
||||
@rpc_call
|
||||
def set_curve_limit(self, curve_limit: int) -> None:
|
||||
"""
|
||||
Set the maximum number of traces to display on the plot widget.
|
||||
|
||||
Args:
|
||||
curve_limit(int): The maximum number of traces to display.
|
||||
"""
|
||||
|
||||
@rpc_call
|
||||
def set_buffer_flush(self, flush_buffer: bool) -> None:
|
||||
"""
|
||||
Set the buffer flush property of the plot widget.
|
||||
|
||||
Args:
|
||||
flush_buffer(bool): True to flush the buffer, False to not flush the buffer.
|
||||
"""
|
||||
|
||||
@rpc_call
|
||||
def set_highlight_last_curve(self, enable: bool) -> None:
|
||||
"""
|
||||
Enable or disable highlighting of the last curve.
|
||||
|
||||
Args:
|
||||
enable(bool): True to enable highlighting of the last curve, False to disable.
|
||||
"""
|
||||
|
||||
@rpc_call
|
||||
def set_colormap(self, colormap: str) -> None:
|
||||
"""
|
||||
Set the colormap of the plot widget.
|
||||
|
||||
Args:
|
||||
colormap(str): The colormap to set.
|
||||
"""
|
||||
|
||||
@rpc_call
|
||||
def set(self, **kwargs):
|
||||
"""
|
||||
Set the properties of the plot widget.
|
||||
|
||||
Args:
|
||||
**kwargs: Keyword arguments for the properties to be set.
|
||||
|
||||
Possible properties:
|
||||
- title: str
|
||||
- x_label: str
|
||||
- y_label: str
|
||||
- x_scale: Literal["linear", "log"]
|
||||
- y_scale: Literal["linear", "log"]
|
||||
- x_lim: tuple
|
||||
- y_lim: tuple
|
||||
- legend_label_size: int
|
||||
"""
|
||||
|
||||
@rpc_call
|
||||
def set_title(self, title: str):
|
||||
"""
|
||||
Set the title of the plot widget.
|
||||
|
||||
Args:
|
||||
title(str): The title to set.
|
||||
"""
|
||||
|
||||
@rpc_call
|
||||
def set_x_label(self, x_label: str):
|
||||
"""
|
||||
Set the x-axis label of the plot widget.
|
||||
|
||||
Args:
|
||||
x_label(str): The x-axis label to set.
|
||||
"""
|
||||
|
||||
@rpc_call
|
||||
def set_y_label(self, y_label: str):
|
||||
"""
|
||||
Set the y-axis label of the plot widget.
|
||||
|
||||
Args:
|
||||
y_label(str): The y-axis label to set.
|
||||
"""
|
||||
|
||||
@rpc_call
|
||||
def set_x_scale(self, x_scale: Literal["linear", "log"]):
|
||||
"""
|
||||
Set the x-axis scale of the plot widget.
|
||||
|
||||
Args:
|
||||
x_scale(str): The x-axis scale to set.
|
||||
"""
|
||||
|
||||
@rpc_call
|
||||
def set_y_scale(self, y_scale: Literal["linear", "log"]):
|
||||
"""
|
||||
Set the y-axis scale of the plot widget.
|
||||
|
||||
Args:
|
||||
y_scale(str): The y-axis scale to set.
|
||||
"""
|
||||
|
||||
@rpc_call
|
||||
def set_x_lim(self, x_lim: tuple):
|
||||
"""
|
||||
Set x-axis limits of the plot widget.
|
||||
|
||||
Args:
|
||||
x_lim(tuple): The x-axis limits to set.
|
||||
"""
|
||||
|
||||
@rpc_call
|
||||
def set_y_lim(self, y_lim: tuple):
|
||||
"""
|
||||
Set y-axis limits of the plot widget.
|
||||
|
||||
Args:
|
||||
y_lim(tuple): The y-axis limits to set.
|
||||
"""
|
||||
|
||||
@rpc_call
|
||||
def set_grid(self, x_grid: bool, y_grid: bool):
|
||||
"""
|
||||
Set the grid of the plot widget.
|
||||
|
||||
Args:
|
||||
x_grid(bool): True to enable the x-grid, False to disable.
|
||||
y_grid(bool): True to enable the y-grid, False to disable.
|
||||
"""
|
||||
|
||||
@rpc_call
|
||||
def set_colormap(self, colormap: str) -> None:
|
||||
"""
|
||||
Set the colormap of the plot widget.
|
||||
|
||||
Args:
|
||||
colormap(str): The colormap to set.
|
||||
"""
|
||||
|
||||
@rpc_call
|
||||
def enable_fps_monitor(self, enabled: bool):
|
||||
"""
|
||||
Enable or disable the FPS monitor
|
||||
|
||||
Args:
|
||||
enabled(bool): True to enable the FPS monitor, False to disable.
|
||||
"""
|
||||
|
||||
@rpc_call
|
||||
def lock_aspect_ratio(self, lock: bool):
|
||||
"""
|
||||
Lock the aspect ratio of the plot widget.
|
||||
|
||||
Args:
|
||||
lock(bool): True to lock the aspect ratio, False to unlock.
|
||||
"""
|
||||
|
||||
@rpc_call
|
||||
def export(self):
|
||||
"""
|
||||
Export the plot widget.
|
||||
"""
|
||||
|
||||
|
||||
class BECPlotBase(RPCBase):
|
||||
@property
|
||||
@rpc_call
|
||||
|
@ -25,9 +25,9 @@ from bec_widgets.widgets.containers.dock.dock import BECDock, DockConfig
|
||||
from bec_widgets.widgets.control.device_control.positioner_box import PositionerBox
|
||||
from bec_widgets.widgets.control.scan_control.scan_control import ScanControl
|
||||
from bec_widgets.widgets.editors.vscode.vscode import VSCodeEditor
|
||||
from bec_widgets.widgets.plots.multi_waveform.multi_waveform_widget import BECMultiWaveformWidget
|
||||
from bec_widgets.widgets.plots_next_gen.image.image import Image
|
||||
from bec_widgets.widgets.plots_next_gen.motor_map.motor_map import MotorMap
|
||||
from bec_widgets.widgets.plots_next_gen.multi_waveform.multi_waveform import MultiWaveform
|
||||
from bec_widgets.widgets.plots_next_gen.scatter_waveform.scatter_waveform import ScatterWaveform
|
||||
from bec_widgets.widgets.plots_next_gen.waveform.waveform import Waveform
|
||||
from bec_widgets.widgets.progress.ring_progress_bar.ring_progress_bar import RingProgressBar
|
||||
@ -103,7 +103,7 @@ class BECDockArea(BECWidget, QWidget):
|
||||
filled=True,
|
||||
),
|
||||
"multi_waveform": MaterialIconAction(
|
||||
icon_name=BECMultiWaveformWidget.ICON_NAME,
|
||||
icon_name=MultiWaveform.ICON_NAME,
|
||||
tooltip="Add Multi Waveform",
|
||||
filled=True,
|
||||
),
|
||||
@ -184,7 +184,7 @@ class BECDockArea(BECWidget, QWidget):
|
||||
lambda: self._create_widget_from_toolbar(widget_name="ScatterWaveform")
|
||||
)
|
||||
self.toolbar.widgets["menu_plots"].widgets["multi_waveform"].triggered.connect(
|
||||
lambda: self._create_widget_from_toolbar(widget_name="BECMultiWaveformWidget")
|
||||
lambda: self._create_widget_from_toolbar(widget_name="MultiWaveform")
|
||||
)
|
||||
self.toolbar.widgets["menu_plots"].widgets["image"].triggered.connect(
|
||||
lambda: self._create_widget_from_toolbar(widget_name="Image")
|
||||
|
@ -1 +0,0 @@
|
||||
{'files': ['multi_waveform_widget.py','multi-waveform_controls.ui']}
|
@ -1,54 +0,0 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
from qtpy.QtDesigner import QDesignerCustomWidgetInterface
|
||||
|
||||
from bec_widgets.utils.bec_designer import designer_material_icon
|
||||
from bec_widgets.widgets.plots.multi_waveform.multi_waveform_widget import BECMultiWaveformWidget
|
||||
|
||||
DOM_XML = """
|
||||
<ui language='c++'>
|
||||
<widget class='BECMultiWaveformWidget' name='bec_multi_waveform_widget'>
|
||||
</widget>
|
||||
</ui>
|
||||
"""
|
||||
|
||||
|
||||
class BECMultiWaveformWidgetPlugin(QDesignerCustomWidgetInterface): # pragma: no cover
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._form_editor = None
|
||||
|
||||
def createWidget(self, parent):
|
||||
t = BECMultiWaveformWidget(parent)
|
||||
return t
|
||||
|
||||
def domXml(self):
|
||||
return DOM_XML
|
||||
|
||||
def group(self):
|
||||
return "BEC Plots"
|
||||
|
||||
def icon(self):
|
||||
return designer_material_icon(BECMultiWaveformWidget.ICON_NAME)
|
||||
|
||||
def includeFile(self):
|
||||
return "bec_multi_waveform_widget"
|
||||
|
||||
def initialize(self, form_editor):
|
||||
self._form_editor = form_editor
|
||||
|
||||
def isContainer(self):
|
||||
return False
|
||||
|
||||
def isInitialized(self):
|
||||
return self._form_editor is not None
|
||||
|
||||
def name(self):
|
||||
return "BECMultiWaveformWidget"
|
||||
|
||||
def toolTip(self):
|
||||
return "BECMultiWaveformWidget"
|
||||
|
||||
def whatsThis(self):
|
||||
return self.toolTip()
|
@ -1,99 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Form</class>
|
||||
<widget class="QWidget" name="Form">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>561</width>
|
||||
<height>86</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_curve_index">
|
||||
<property name="text">
|
||||
<string>Curve Index</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSlider" name="slider_index">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QSpinBox" name="spinbox_index"/>
|
||||
</item>
|
||||
<item row="0" column="3" colspan="3">
|
||||
<widget class="QCheckBox" name="checkbox_highlight">
|
||||
<property name="text">
|
||||
<string>Highlight always last curve</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_opacity">
|
||||
<property name="text">
|
||||
<string>Opacity</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSlider" name="slider_opacity">
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QLabel" name="label_max_trace">
|
||||
<property name="text">
|
||||
<string>Max Trace</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QSpinBox" name="spinbox_max_trace">
|
||||
<property name="toolTip">
|
||||
<string>How many curves should be displayed</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>500</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>200</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="5">
|
||||
<widget class="QCheckBox" name="checkbox_flush_buffer">
|
||||
<property name="toolTip">
|
||||
<string>If hiddne curves should be deleted.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Flush Buffer</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QSpinBox" name="spinbox_opacity">
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
@ -1,536 +0,0 @@
|
||||
import os
|
||||
from typing import Literal
|
||||
|
||||
import pyqtgraph as pg
|
||||
from bec_lib.device import ReadoutPriority
|
||||
from bec_lib.logger import bec_logger
|
||||
from qtpy.QtCore import Slot
|
||||
from qtpy.QtWidgets import QVBoxLayout, QWidget
|
||||
|
||||
from bec_widgets.qt_utils.error_popups import SafeSlot
|
||||
from bec_widgets.qt_utils.settings_dialog import SettingsDialog
|
||||
from bec_widgets.qt_utils.toolbar import (
|
||||
DeviceSelectionAction,
|
||||
MaterialIconAction,
|
||||
ModularToolBar,
|
||||
SeparatorAction,
|
||||
WidgetAction,
|
||||
)
|
||||
from bec_widgets.utils import UILoader
|
||||
from bec_widgets.utils.bec_widget import BECWidget
|
||||
from bec_widgets.widgets.containers.figure import BECFigure
|
||||
from bec_widgets.widgets.containers.figure.plots.axis_settings import AxisSettings
|
||||
from bec_widgets.widgets.containers.figure.plots.multi_waveform.multi_waveform import (
|
||||
BECMultiWaveformConfig,
|
||||
)
|
||||
from bec_widgets.widgets.control.device_input.base_classes.device_input_base import BECDeviceFilter
|
||||
from bec_widgets.widgets.control.device_input.device_combobox.device_combobox import DeviceComboBox
|
||||
from bec_widgets.widgets.utility.visual.colormap_widget.colormap_widget import BECColorMapWidget
|
||||
|
||||
logger = bec_logger.logger
|
||||
|
||||
|
||||
class BECMultiWaveformWidget(BECWidget, QWidget):
|
||||
PLUGIN = True
|
||||
ICON_NAME = "ssid_chart"
|
||||
USER_ACCESS = [
|
||||
"curves",
|
||||
"set_monitor",
|
||||
"set_curve_highlight",
|
||||
"set_opacity",
|
||||
"set_curve_limit",
|
||||
"set_buffer_flush",
|
||||
"set_highlight_last_curve",
|
||||
"set_colormap",
|
||||
"set",
|
||||
"set_title",
|
||||
"set_x_label",
|
||||
"set_y_label",
|
||||
"set_x_scale",
|
||||
"set_y_scale",
|
||||
"set_x_lim",
|
||||
"set_y_lim",
|
||||
"set_grid",
|
||||
"set_colormap",
|
||||
"enable_fps_monitor",
|
||||
"lock_aspect_ratio",
|
||||
"export",
|
||||
]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
parent: QWidget | None = None,
|
||||
config: BECMultiWaveformConfig | dict = None,
|
||||
client=None,
|
||||
gui_id: str | None = None,
|
||||
**kwargs,
|
||||
) -> None:
|
||||
if config is None:
|
||||
config = BECMultiWaveformConfig(widget_class=self.__class__.__name__)
|
||||
else:
|
||||
if isinstance(config, dict):
|
||||
config = BECMultiWaveformConfig(**config)
|
||||
super().__init__(client=client, gui_id=gui_id, **kwargs)
|
||||
QWidget.__init__(self, parent)
|
||||
|
||||
self.layout = QVBoxLayout(self)
|
||||
self.layout.setSpacing(0)
|
||||
self.layout.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
self.fig = BECFigure()
|
||||
self.colormap_button = BECColorMapWidget(cmap="magma")
|
||||
self.toolbar = ModularToolBar(
|
||||
actions={
|
||||
"monitor": DeviceSelectionAction(
|
||||
"",
|
||||
DeviceComboBox(
|
||||
device_filter=BECDeviceFilter.DEVICE,
|
||||
readout_priority_filter=ReadoutPriority.ASYNC,
|
||||
),
|
||||
),
|
||||
"connect": MaterialIconAction(icon_name="link", tooltip="Connect Device"),
|
||||
"separator_0": SeparatorAction(),
|
||||
"colormap": WidgetAction(widget=self.colormap_button),
|
||||
"separator_1": SeparatorAction(),
|
||||
"save": MaterialIconAction(icon_name="save", tooltip="Open Export Dialog"),
|
||||
"matplotlib": MaterialIconAction(
|
||||
icon_name="photo_library", tooltip="Open Matplotlib Plot"
|
||||
),
|
||||
"separator_2": SeparatorAction(),
|
||||
"drag_mode": MaterialIconAction(
|
||||
icon_name="drag_pan", tooltip="Drag Mouse Mode", checkable=True
|
||||
),
|
||||
"rectangle_mode": MaterialIconAction(
|
||||
icon_name="frame_inspect", tooltip="Rectangle Zoom Mode", checkable=True
|
||||
),
|
||||
"auto_range": MaterialIconAction(
|
||||
icon_name="open_in_full", tooltip="Autorange Plot"
|
||||
),
|
||||
"crosshair": MaterialIconAction(
|
||||
icon_name="point_scan", tooltip="Show Crosshair", checkable=True
|
||||
),
|
||||
"separator_3": SeparatorAction(),
|
||||
"fps_monitor": MaterialIconAction(
|
||||
icon_name="speed", tooltip="Show FPS Monitor", checkable=True
|
||||
),
|
||||
"axis_settings": MaterialIconAction(
|
||||
icon_name="settings", tooltip="Open Configuration Dialog"
|
||||
),
|
||||
},
|
||||
target_widget=self,
|
||||
)
|
||||
|
||||
self.layout.addWidget(self.toolbar)
|
||||
self.layout.addWidget(self.fig)
|
||||
|
||||
self.waveform = self.fig.multi_waveform() # FIXME config should be injected here
|
||||
self.config = config
|
||||
|
||||
self.create_multi_waveform_controls()
|
||||
|
||||
self._hook_actions()
|
||||
self.waveform.monitor_signal_updated.connect(self.update_controls_limits)
|
||||
|
||||
def create_multi_waveform_controls(self):
|
||||
"""
|
||||
Create the controls for the multi waveform widget.
|
||||
"""
|
||||
current_path = os.path.dirname(__file__)
|
||||
self.controls = UILoader(self).loader(
|
||||
os.path.join(current_path, "multi_waveform_controls.ui")
|
||||
)
|
||||
self.layout.addWidget(self.controls)
|
||||
|
||||
# Hook default controls properties
|
||||
self.controls.checkbox_highlight.setChecked(self.config.highlight_last_curve)
|
||||
self.controls.spinbox_opacity.setValue(self.config.opacity)
|
||||
self.controls.slider_opacity.setValue(self.config.opacity)
|
||||
self.controls.spinbox_max_trace.setValue(self.config.curve_limit)
|
||||
self.controls.checkbox_flush_buffer.setChecked(self.config.flush_buffer)
|
||||
|
||||
# Connect signals
|
||||
self.controls.spinbox_max_trace.valueChanged.connect(self.set_curve_limit)
|
||||
self.controls.checkbox_flush_buffer.toggled.connect(self.set_buffer_flush)
|
||||
self.controls.slider_opacity.valueChanged.connect(self.controls.spinbox_opacity.setValue)
|
||||
self.controls.spinbox_opacity.valueChanged.connect(self.controls.slider_opacity.setValue)
|
||||
self.controls.slider_opacity.valueChanged.connect(self.set_opacity)
|
||||
self.controls.spinbox_opacity.valueChanged.connect(self.set_opacity)
|
||||
self.controls.slider_index.valueChanged.connect(self.controls.spinbox_index.setValue)
|
||||
self.controls.spinbox_index.valueChanged.connect(self.controls.slider_index.setValue)
|
||||
self.controls.slider_index.valueChanged.connect(self.set_curve_highlight)
|
||||
self.controls.spinbox_index.valueChanged.connect(self.set_curve_highlight)
|
||||
self.controls.checkbox_highlight.toggled.connect(self.set_highlight_last_curve)
|
||||
|
||||
# Trigger first round of settings
|
||||
self.set_curve_limit(self.config.curve_limit)
|
||||
self.set_opacity(self.config.opacity)
|
||||
self.set_highlight_last_curve(self.config.highlight_last_curve)
|
||||
|
||||
@Slot()
|
||||
def update_controls_limits(self):
|
||||
"""
|
||||
Update the limits of the controls.
|
||||
"""
|
||||
num_curves = len(self.waveform.curves)
|
||||
if num_curves == 0:
|
||||
num_curves = 1 # Avoid setting max to 0
|
||||
current_index = num_curves - 1
|
||||
self.controls.slider_index.setMinimum(0)
|
||||
self.controls.slider_index.setMaximum(self.waveform.number_of_visible_curves - 1)
|
||||
self.controls.spinbox_index.setMaximum(self.waveform.number_of_visible_curves - 1)
|
||||
if self.controls.checkbox_highlight.isChecked():
|
||||
self.controls.slider_index.setValue(current_index)
|
||||
self.controls.spinbox_index.setValue(current_index)
|
||||
|
||||
def _hook_actions(self):
|
||||
self.toolbar.widgets["connect"].action.triggered.connect(self._connect_action)
|
||||
# Separator 0
|
||||
self.toolbar.widgets["save"].action.triggered.connect(self.export)
|
||||
self.toolbar.widgets["matplotlib"].action.triggered.connect(self.export_to_matplotlib)
|
||||
self.toolbar.widgets["colormap"].widget.colormap_changed_signal.connect(self.set_colormap)
|
||||
# Separator 1
|
||||
self.toolbar.widgets["drag_mode"].action.triggered.connect(self.enable_mouse_pan_mode)
|
||||
self.toolbar.widgets["rectangle_mode"].action.triggered.connect(
|
||||
self.enable_mouse_rectangle_mode
|
||||
)
|
||||
self.toolbar.widgets["auto_range"].action.triggered.connect(self._auto_range_from_toolbar)
|
||||
self.toolbar.widgets["crosshair"].action.triggered.connect(self.waveform.toggle_crosshair)
|
||||
# Separator 2
|
||||
self.toolbar.widgets["fps_monitor"].action.triggered.connect(self.enable_fps_monitor)
|
||||
self.toolbar.widgets["axis_settings"].action.triggered.connect(self.show_axis_settings)
|
||||
|
||||
###################################
|
||||
# Dialog Windows
|
||||
###################################
|
||||
@SafeSlot(popup_error=True)
|
||||
def _connect_action(self):
|
||||
monitor_combo = self.toolbar.widgets["monitor"].device_combobox
|
||||
monitor_name = monitor_combo.currentText()
|
||||
self.set_monitor(monitor=monitor_name)
|
||||
monitor_combo.setStyleSheet("QComboBox { background-color: " "; }")
|
||||
|
||||
def show_axis_settings(self):
|
||||
dialog = SettingsDialog(
|
||||
self,
|
||||
settings_widget=AxisSettings(),
|
||||
window_title="Axis Settings",
|
||||
config=self.waveform._config_dict["axis"],
|
||||
)
|
||||
dialog.exec()
|
||||
|
||||
########################################
|
||||
# User Access Methods from MultiWaveform
|
||||
########################################
|
||||
@property
|
||||
def curves(self) -> list[pg.PlotDataItem]:
|
||||
"""
|
||||
Get the curves of the plot widget as a list
|
||||
Returns:
|
||||
list: List of curves.
|
||||
"""
|
||||
return list(self.waveform.curves)
|
||||
|
||||
@curves.setter
|
||||
def curves(self, value: list[pg.PlotDataItem]):
|
||||
self.waveform.curves = value
|
||||
|
||||
@SafeSlot(popup_error=True)
|
||||
def set_monitor(self, monitor: str) -> None:
|
||||
"""
|
||||
Set the monitor of the plot widget.
|
||||
|
||||
Args:
|
||||
monitor(str): The monitor to set.
|
||||
"""
|
||||
self.waveform.set_monitor(monitor)
|
||||
if self.toolbar.widgets["monitor"].device_combobox.currentText() != monitor:
|
||||
self.toolbar.widgets["monitor"].device_combobox.setCurrentText(monitor)
|
||||
self.toolbar.widgets["monitor"].device_combobox.setStyleSheet(
|
||||
"QComboBox { background-color: " "; }"
|
||||
)
|
||||
|
||||
@SafeSlot(int)
|
||||
def set_curve_highlight(self, index: int) -> None:
|
||||
"""
|
||||
Set the curve highlight of the plot widget by index
|
||||
|
||||
Args:
|
||||
index(int): The index of the curve to highlight.
|
||||
"""
|
||||
if self.controls.checkbox_highlight.isChecked():
|
||||
# If always highlighting the last curve, set index to -1
|
||||
self.waveform.set_curve_highlight(-1)
|
||||
else:
|
||||
self.waveform.set_curve_highlight(index)
|
||||
|
||||
@SafeSlot(int)
|
||||
def set_opacity(self, opacity: int) -> None:
|
||||
"""
|
||||
Set the opacity of the plot widget.
|
||||
|
||||
Args:
|
||||
opacity(int): The opacity to set.
|
||||
"""
|
||||
self.waveform.set_opacity(opacity)
|
||||
|
||||
@SafeSlot(int)
|
||||
def set_curve_limit(self, curve_limit: int) -> None:
|
||||
"""
|
||||
Set the maximum number of traces to display on the plot widget.
|
||||
|
||||
Args:
|
||||
curve_limit(int): The maximum number of traces to display.
|
||||
"""
|
||||
flush_buffer = self.controls.checkbox_flush_buffer.isChecked()
|
||||
self.waveform.set_curve_limit(curve_limit, flush_buffer)
|
||||
self.update_controls_limits()
|
||||
|
||||
@SafeSlot(bool)
|
||||
def set_buffer_flush(self, flush_buffer: bool) -> None:
|
||||
"""
|
||||
Set the buffer flush property of the plot widget.
|
||||
|
||||
Args:
|
||||
flush_buffer(bool): True to flush the buffer, False to not flush the buffer.
|
||||
"""
|
||||
curve_limit = self.controls.spinbox_max_trace.value()
|
||||
self.waveform.set_curve_limit(curve_limit, flush_buffer)
|
||||
self.update_controls_limits()
|
||||
|
||||
@SafeSlot(bool)
|
||||
def set_highlight_last_curve(self, enable: bool) -> None:
|
||||
"""
|
||||
Enable or disable highlighting of the last curve.
|
||||
|
||||
Args:
|
||||
enable(bool): True to enable highlighting of the last curve, False to disable.
|
||||
"""
|
||||
self.waveform.config.highlight_last_curve = enable
|
||||
if enable:
|
||||
self.controls.slider_index.setEnabled(False)
|
||||
self.controls.spinbox_index.setEnabled(False)
|
||||
self.controls.checkbox_highlight.setChecked(True)
|
||||
self.waveform.set_curve_highlight(-1)
|
||||
else:
|
||||
self.controls.slider_index.setEnabled(True)
|
||||
self.controls.spinbox_index.setEnabled(True)
|
||||
self.controls.checkbox_highlight.setChecked(False)
|
||||
index = self.controls.spinbox_index.value()
|
||||
self.waveform.set_curve_highlight(index)
|
||||
|
||||
@SafeSlot()
|
||||
def set_colormap(self, colormap: str) -> None:
|
||||
"""
|
||||
Set the colormap of the plot widget.
|
||||
|
||||
Args:
|
||||
colormap(str): The colormap to set.
|
||||
"""
|
||||
self.waveform.set_colormap(colormap)
|
||||
|
||||
###################################
|
||||
# User Access Methods from PlotBase
|
||||
###################################
|
||||
def set(self, **kwargs):
|
||||
"""
|
||||
Set the properties of the plot widget.
|
||||
|
||||
Args:
|
||||
**kwargs: Keyword arguments for the properties to be set.
|
||||
|
||||
Possible properties:
|
||||
- title: str
|
||||
- x_label: str
|
||||
- y_label: str
|
||||
- x_scale: Literal["linear", "log"]
|
||||
- y_scale: Literal["linear", "log"]
|
||||
- x_lim: tuple
|
||||
- y_lim: tuple
|
||||
- legend_label_size: int
|
||||
"""
|
||||
self.waveform.set(**kwargs)
|
||||
|
||||
def set_title(self, title: str):
|
||||
"""
|
||||
Set the title of the plot widget.
|
||||
|
||||
Args:
|
||||
title(str): The title to set.
|
||||
"""
|
||||
self.waveform.set_title(title)
|
||||
|
||||
def set_x_label(self, x_label: str):
|
||||
"""
|
||||
Set the x-axis label of the plot widget.
|
||||
|
||||
Args:
|
||||
x_label(str): The x-axis label to set.
|
||||
"""
|
||||
self.waveform.set_x_label(x_label)
|
||||
|
||||
def set_y_label(self, y_label: str):
|
||||
"""
|
||||
Set the y-axis label of the plot widget.
|
||||
|
||||
Args:
|
||||
y_label(str): The y-axis label to set.
|
||||
"""
|
||||
self.waveform.set_y_label(y_label)
|
||||
|
||||
def set_x_scale(self, x_scale: Literal["linear", "log"]):
|
||||
"""
|
||||
Set the x-axis scale of the plot widget.
|
||||
|
||||
Args:
|
||||
x_scale(str): The x-axis scale to set.
|
||||
"""
|
||||
self.waveform.set_x_scale(x_scale)
|
||||
|
||||
def set_y_scale(self, y_scale: Literal["linear", "log"]):
|
||||
"""
|
||||
Set the y-axis scale of the plot widget.
|
||||
|
||||
Args:
|
||||
y_scale(str): The y-axis scale to set.
|
||||
"""
|
||||
self.waveform.set_y_scale(y_scale)
|
||||
|
||||
def set_x_lim(self, x_lim: tuple):
|
||||
"""
|
||||
Set x-axis limits of the plot widget.
|
||||
|
||||
Args:
|
||||
x_lim(tuple): The x-axis limits to set.
|
||||
"""
|
||||
self.waveform.set_x_lim(x_lim)
|
||||
|
||||
def set_y_lim(self, y_lim: tuple):
|
||||
"""
|
||||
Set y-axis limits of the plot widget.
|
||||
|
||||
Args:
|
||||
y_lim(tuple): The y-axis limits to set.
|
||||
"""
|
||||
self.waveform.set_y_lim(y_lim)
|
||||
|
||||
def set_legend_label_size(self, legend_label_size: int):
|
||||
"""
|
||||
Set the legend label size of the plot widget.
|
||||
|
||||
Args:
|
||||
legend_label_size(int): The legend label size to set.
|
||||
"""
|
||||
self.waveform.set_legend_label_size(legend_label_size)
|
||||
|
||||
def set_auto_range(self, enabled: bool, axis: str = "xy"):
|
||||
"""
|
||||
Set the auto range of the plot widget.
|
||||
|
||||
Args:
|
||||
enabled(bool): True to enable auto range, False to disable.
|
||||
axis(str): The axis to set the auto range for. Default is "xy".
|
||||
"""
|
||||
self.waveform.set_auto_range(enabled, axis)
|
||||
|
||||
def enable_fps_monitor(self, enabled: bool):
|
||||
"""
|
||||
Enable or disable the FPS monitor
|
||||
|
||||
Args:
|
||||
enabled(bool): True to enable the FPS monitor, False to disable.
|
||||
"""
|
||||
self.waveform.enable_fps_monitor(enabled)
|
||||
if self.toolbar.widgets["fps_monitor"].action.isChecked() != enabled:
|
||||
self.toolbar.widgets["fps_monitor"].action.setChecked(enabled)
|
||||
|
||||
@SafeSlot()
|
||||
def _auto_range_from_toolbar(self):
|
||||
"""
|
||||
Set the auto range of the plot widget from the toolbar.
|
||||
"""
|
||||
self.waveform.set_auto_range(True, "xy")
|
||||
|
||||
def set_grid(self, x_grid: bool, y_grid: bool):
|
||||
"""
|
||||
Set the grid of the plot widget.
|
||||
|
||||
Args:
|
||||
x_grid(bool): True to enable the x-grid, False to disable.
|
||||
y_grid(bool): True to enable the y-grid, False to disable.
|
||||
"""
|
||||
self.waveform.set_grid(x_grid, y_grid)
|
||||
|
||||
def set_outer_axes(self, show: bool):
|
||||
"""
|
||||
Set the outer axes of the plot widget.
|
||||
|
||||
Args:
|
||||
show(bool): True to show the outer axes, False to hide.
|
||||
"""
|
||||
self.waveform.set_outer_axes(show)
|
||||
|
||||
def lock_aspect_ratio(self, lock: bool):
|
||||
"""
|
||||
Lock the aspect ratio of the plot widget.
|
||||
|
||||
Args:
|
||||
lock(bool): True to lock the aspect ratio, False to unlock.
|
||||
"""
|
||||
self.waveform.lock_aspect_ratio(lock)
|
||||
|
||||
@SafeSlot()
|
||||
def enable_mouse_rectangle_mode(self):
|
||||
"""
|
||||
Enable the mouse rectangle mode of the plot widget.
|
||||
"""
|
||||
self.toolbar.widgets["rectangle_mode"].action.setChecked(True)
|
||||
self.toolbar.widgets["drag_mode"].action.setChecked(False)
|
||||
self.waveform.plot_item.getViewBox().setMouseMode(pg.ViewBox.RectMode)
|
||||
|
||||
@SafeSlot()
|
||||
def enable_mouse_pan_mode(self):
|
||||
"""
|
||||
Enable the mouse pan mode of the plot widget.
|
||||
"""
|
||||
self.toolbar.widgets["drag_mode"].action.setChecked(True)
|
||||
self.toolbar.widgets["rectangle_mode"].action.setChecked(False)
|
||||
self.waveform.plot_item.getViewBox().setMouseMode(pg.ViewBox.PanMode)
|
||||
|
||||
def export(self):
|
||||
"""
|
||||
Export the plot widget.
|
||||
"""
|
||||
self.waveform.export()
|
||||
|
||||
def export_to_matplotlib(self):
|
||||
"""
|
||||
Export the plot widget to matplotlib.
|
||||
"""
|
||||
try:
|
||||
import matplotlib as mpl
|
||||
except ImportError:
|
||||
self.warning_util.show_warning(
|
||||
title="Matplotlib not installed",
|
||||
message="Matplotlib is required for this feature.",
|
||||
detailed_text="Please install matplotlib in your Python environment by using 'pip install matplotlib'.",
|
||||
)
|
||||
return
|
||||
self.waveform.export_to_matplotlib()
|
||||
|
||||
#######################################
|
||||
# User Access Methods from BECConnector
|
||||
######################################
|
||||
def cleanup(self):
|
||||
self.fig.cleanup()
|
||||
return super().cleanup()
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
import sys
|
||||
|
||||
from qtpy.QtWidgets import QApplication
|
||||
|
||||
app = QApplication(sys.argv)
|
||||
widget = BECMultiWaveformWidget()
|
||||
widget.show()
|
||||
sys.exit(app.exec())
|
@ -1,17 +0,0 @@
|
||||
def main(): # pragma: no cover
|
||||
from qtpy import PYSIDE6
|
||||
|
||||
if not PYSIDE6:
|
||||
print("PYSIDE6 is not available in the environment. Cannot patch designer.")
|
||||
return
|
||||
from PySide6.QtDesigner import QPyDesignerCustomWidgetCollection
|
||||
|
||||
from bec_widgets.widgets.plots.multi_waveform.bec_multi_waveform_widget_plugin import (
|
||||
BECMultiWaveformWidgetPlugin,
|
||||
)
|
||||
|
||||
QPyDesignerCustomWidgetCollection.addCustomWidget(BECMultiWaveformWidgetPlugin())
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
main()
|
@ -141,11 +141,8 @@ def test_toolbar_add_plot_motor_map(bec_dock_area):
|
||||
|
||||
def test_toolbar_add_multi_waveform(bec_dock_area):
|
||||
bec_dock_area.toolbar.widgets["menu_plots"].widgets["multi_waveform"].trigger()
|
||||
assert "BECMultiWaveformWidget_0" in bec_dock_area.panels
|
||||
assert (
|
||||
bec_dock_area.panels["BECMultiWaveformWidget_0"].widgets[0].config.widget_class
|
||||
== "BECMultiWaveformWidget"
|
||||
)
|
||||
assert "MultiWaveform_0" in bec_dock_area.panels
|
||||
assert bec_dock_area.panels["MultiWaveform_0"].widgets[0].config.widget_class == "MultiWaveform"
|
||||
|
||||
|
||||
def test_toolbar_add_device_positioner_box(bec_dock_area):
|
||||
|
@ -1,296 +0,0 @@
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from qtpy.QtGui import QColor
|
||||
from qtpy.QtWidgets import QApplication
|
||||
|
||||
from bec_widgets.qt_utils.settings_dialog import SettingsDialog
|
||||
from bec_widgets.utils.colors import apply_theme, get_theme_palette, set_theme
|
||||
from bec_widgets.widgets.containers.figure.plots.axis_settings import AxisSettings
|
||||
from bec_widgets.widgets.plots.multi_waveform.multi_waveform_widget import BECMultiWaveformWidget
|
||||
|
||||
from .client_mocks import mocked_client
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def multi_waveform_widget(qtbot, mocked_client):
|
||||
widget = BECMultiWaveformWidget(client=mocked_client())
|
||||
qtbot.addWidget(widget)
|
||||
qtbot.waitExposed(widget)
|
||||
return widget
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_waveform(multi_waveform_widget):
|
||||
waveform_mock = MagicMock()
|
||||
multi_waveform_widget.waveform = waveform_mock
|
||||
return waveform_mock
|
||||
|
||||
|
||||
def test_multi_waveform_widget_init(multi_waveform_widget):
|
||||
assert multi_waveform_widget is not None
|
||||
assert multi_waveform_widget.client is not None
|
||||
assert isinstance(multi_waveform_widget, BECMultiWaveformWidget)
|
||||
assert multi_waveform_widget.config.widget_class == "BECMultiWaveformWidget"
|
||||
|
||||
|
||||
###################################
|
||||
# Wrapper methods for Waveform
|
||||
###################################
|
||||
|
||||
|
||||
def test_multi_waveform_widget_set_monitor(multi_waveform_widget, mock_waveform):
|
||||
multi_waveform_widget.set_monitor("waveform1d")
|
||||
mock_waveform.set_monitor.assert_called_once_with("waveform1d")
|
||||
|
||||
|
||||
def test_multi_waveform_widget_set_curve_highlight_last_active(
|
||||
multi_waveform_widget, mock_waveform
|
||||
):
|
||||
multi_waveform_widget.set_curve_highlight(1)
|
||||
mock_waveform.set_curve_highlight.assert_called_once_with(-1)
|
||||
|
||||
|
||||
def test_multi_waveform_widget_set_curve_highlight_last_not_active(
|
||||
multi_waveform_widget, mock_waveform
|
||||
):
|
||||
multi_waveform_widget.set_highlight_last_curve(False)
|
||||
multi_waveform_widget.set_curve_highlight(1)
|
||||
mock_waveform.set_curve_highlight.assert_called_with(1)
|
||||
|
||||
|
||||
def test_multi_waveform_widget_set_opacity(multi_waveform_widget, mock_waveform):
|
||||
multi_waveform_widget.set_opacity(50)
|
||||
mock_waveform.set_opacity.assert_called_once_with(50)
|
||||
|
||||
|
||||
def test_multi_waveform_widget_set_curve_limit(multi_waveform_widget, mock_waveform):
|
||||
multi_waveform_widget.set_curve_limit(10)
|
||||
mock_waveform.set_curve_limit.assert_called_once_with(
|
||||
10, multi_waveform_widget.controls.checkbox_flush_buffer.isChecked()
|
||||
)
|
||||
|
||||
|
||||
def test_multi_waveform_widget_set_buffer_flush(multi_waveform_widget, mock_waveform):
|
||||
multi_waveform_widget.set_buffer_flush(True)
|
||||
mock_waveform.set_curve_limit.assert_called_once_with(
|
||||
multi_waveform_widget.controls.spinbox_max_trace.value(), True
|
||||
)
|
||||
|
||||
|
||||
def test_multi_waveform_widget_set_highlight_last_curve(multi_waveform_widget, mock_waveform):
|
||||
multi_waveform_widget.set_highlight_last_curve(True)
|
||||
assert multi_waveform_widget.waveform.config.highlight_last_curve is True
|
||||
assert not multi_waveform_widget.controls.slider_index.isEnabled()
|
||||
assert not multi_waveform_widget.controls.spinbox_index.isEnabled()
|
||||
mock_waveform.set_curve_highlight.assert_called_once_with(-1)
|
||||
|
||||
|
||||
def test_multi_waveform_widget_set_colormap(multi_waveform_widget, mock_waveform):
|
||||
multi_waveform_widget.set_colormap("viridis")
|
||||
mock_waveform.set_colormap.assert_called_once_with("viridis")
|
||||
|
||||
|
||||
def test_multi_waveform_widget_set_base(multi_waveform_widget, mock_waveform):
|
||||
multi_waveform_widget.set(
|
||||
title="Test Title",
|
||||
x_label="X Label",
|
||||
y_label="Y Label",
|
||||
x_scale="linear",
|
||||
y_scale="log",
|
||||
x_lim=(0, 10),
|
||||
y_lim=(0, 10),
|
||||
)
|
||||
mock_waveform.set.assert_called_once_with(
|
||||
title="Test Title",
|
||||
x_label="X Label",
|
||||
y_label="Y Label",
|
||||
x_scale="linear",
|
||||
y_scale="log",
|
||||
x_lim=(0, 10),
|
||||
y_lim=(0, 10),
|
||||
)
|
||||
|
||||
|
||||
###################################
|
||||
# Toolbar interactions
|
||||
###################################
|
||||
|
||||
|
||||
def test_toolbar_connect_action_triggered(multi_waveform_widget, qtbot):
|
||||
action_connect = multi_waveform_widget.toolbar.widgets["connect"].action
|
||||
device_combobox = multi_waveform_widget.toolbar.widgets["monitor"].device_combobox
|
||||
device_combobox.addItem("test_monitor")
|
||||
device_combobox.setCurrentText("test_monitor")
|
||||
|
||||
with patch.object(multi_waveform_widget, "set_monitor") as mock_set_monitor:
|
||||
action_connect.trigger()
|
||||
mock_set_monitor.assert_called_once_with(monitor="test_monitor")
|
||||
|
||||
|
||||
def test_toolbar_drag_mode_action_triggered(multi_waveform_widget, qtbot):
|
||||
action_drag = multi_waveform_widget.toolbar.widgets["drag_mode"].action
|
||||
action_rectangle = multi_waveform_widget.toolbar.widgets["rectangle_mode"].action
|
||||
action_drag.trigger()
|
||||
assert action_drag.isChecked() == True
|
||||
assert action_rectangle.isChecked() == False
|
||||
|
||||
|
||||
def test_toolbar_rectangle_mode_action_triggered(multi_waveform_widget, qtbot):
|
||||
action_drag = multi_waveform_widget.toolbar.widgets["drag_mode"].action
|
||||
action_rectangle = multi_waveform_widget.toolbar.widgets["rectangle_mode"].action
|
||||
action_rectangle.trigger()
|
||||
assert action_drag.isChecked() == False
|
||||
assert action_rectangle.isChecked() == True
|
||||
|
||||
|
||||
def test_toolbar_auto_range_action_triggered(multi_waveform_widget, mock_waveform, qtbot):
|
||||
action = multi_waveform_widget.toolbar.widgets["auto_range"].action
|
||||
action.trigger()
|
||||
qtbot.wait(200)
|
||||
mock_waveform.set_auto_range.assert_called_once_with(True, "xy")
|
||||
|
||||
|
||||
###################################
|
||||
# Control Panel interactions
|
||||
###################################
|
||||
|
||||
|
||||
def test_controls_opacity_slider(multi_waveform_widget, mock_waveform):
|
||||
multi_waveform_widget.controls.slider_opacity.setValue(75)
|
||||
mock_waveform.set_opacity.assert_called_with(75)
|
||||
assert multi_waveform_widget.controls.spinbox_opacity.value() == 75
|
||||
|
||||
|
||||
def test_controls_opacity_spinbox(multi_waveform_widget, mock_waveform):
|
||||
multi_waveform_widget.controls.spinbox_opacity.setValue(25)
|
||||
mock_waveform.set_opacity.assert_called_with(25)
|
||||
assert multi_waveform_widget.controls.slider_opacity.value() == 25
|
||||
|
||||
|
||||
def test_controls_max_trace_spinbox(multi_waveform_widget, mock_waveform):
|
||||
multi_waveform_widget.controls.spinbox_max_trace.setValue(15)
|
||||
mock_waveform.set_curve_limit.assert_called_with(
|
||||
15, multi_waveform_widget.controls.checkbox_flush_buffer.isChecked()
|
||||
)
|
||||
|
||||
|
||||
def test_controls_flush_buffer_checkbox(multi_waveform_widget, mock_waveform):
|
||||
multi_waveform_widget.controls.checkbox_flush_buffer.setChecked(True)
|
||||
mock_waveform.set_curve_limit.assert_called_with(
|
||||
multi_waveform_widget.controls.spinbox_max_trace.value(), True
|
||||
)
|
||||
|
||||
|
||||
def test_controls_highlight_checkbox(multi_waveform_widget, mock_waveform):
|
||||
multi_waveform_widget.controls.checkbox_highlight.setChecked(False)
|
||||
assert multi_waveform_widget.waveform.config.highlight_last_curve is False
|
||||
assert multi_waveform_widget.controls.slider_index.isEnabled()
|
||||
assert multi_waveform_widget.controls.spinbox_index.isEnabled()
|
||||
index = multi_waveform_widget.controls.spinbox_index.value()
|
||||
mock_waveform.set_curve_highlight.assert_called_with(index)
|
||||
|
||||
|
||||
###################################
|
||||
# Axis Settings Dialog Tests
|
||||
###################################
|
||||
|
||||
|
||||
def show_axis_dialog(qtbot, multi_waveform_widget):
|
||||
axis_dialog = SettingsDialog(
|
||||
multi_waveform_widget,
|
||||
settings_widget=AxisSettings(),
|
||||
window_title="Axis Settings",
|
||||
config=multi_waveform_widget.waveform._config_dict["axis"],
|
||||
)
|
||||
qtbot.addWidget(axis_dialog)
|
||||
qtbot.waitExposed(axis_dialog)
|
||||
return axis_dialog
|
||||
|
||||
|
||||
def test_axis_dialog_with_axis_limits(qtbot, multi_waveform_widget):
|
||||
multi_waveform_widget.set(
|
||||
title="Test Title",
|
||||
x_label="X Label",
|
||||
y_label="Y Label",
|
||||
x_scale="linear",
|
||||
y_scale="log",
|
||||
x_lim=(0, 10),
|
||||
y_lim=(0, 10),
|
||||
)
|
||||
|
||||
axis_dialog = show_axis_dialog(qtbot, multi_waveform_widget)
|
||||
|
||||
assert axis_dialog is not None
|
||||
assert axis_dialog.widget.ui.plot_title.text() == "Test Title"
|
||||
assert axis_dialog.widget.ui.x_label.text() == "X Label"
|
||||
assert axis_dialog.widget.ui.y_label.text() == "Y Label"
|
||||
assert axis_dialog.widget.ui.x_scale.currentText() == "linear"
|
||||
assert axis_dialog.widget.ui.y_scale.currentText() == "log"
|
||||
assert axis_dialog.widget.ui.x_min.value() == 0
|
||||
assert axis_dialog.widget.ui.x_max.value() == 10
|
||||
assert axis_dialog.widget.ui.y_min.value() == 0
|
||||
assert axis_dialog.widget.ui.y_max.value() == 10
|
||||
|
||||
|
||||
def test_axis_dialog_set_properties(qtbot, multi_waveform_widget):
|
||||
axis_dialog = show_axis_dialog(qtbot, multi_waveform_widget)
|
||||
|
||||
axis_dialog.widget.ui.plot_title.setText("New Title")
|
||||
axis_dialog.widget.ui.x_label.setText("New X Label")
|
||||
axis_dialog.widget.ui.y_label.setText("New Y Label")
|
||||
axis_dialog.widget.ui.x_scale.setCurrentText("log")
|
||||
axis_dialog.widget.ui.y_scale.setCurrentText("linear")
|
||||
axis_dialog.widget.ui.x_min.setValue(5)
|
||||
axis_dialog.widget.ui.x_max.setValue(15)
|
||||
axis_dialog.widget.ui.y_min.setValue(5)
|
||||
axis_dialog.widget.ui.y_max.setValue(15)
|
||||
|
||||
axis_dialog.accept()
|
||||
|
||||
assert multi_waveform_widget.waveform.config.axis.title == "New Title"
|
||||
assert multi_waveform_widget.waveform.config.axis.x_label == "New X Label"
|
||||
assert multi_waveform_widget.waveform.config.axis.y_label == "New Y Label"
|
||||
assert multi_waveform_widget.waveform.config.axis.x_scale == "log"
|
||||
assert multi_waveform_widget.waveform.config.axis.y_scale == "linear"
|
||||
assert multi_waveform_widget.waveform.config.axis.x_lim == (5, 15)
|
||||
assert multi_waveform_widget.waveform.config.axis.y_lim == (5, 15)
|
||||
|
||||
|
||||
###################################
|
||||
# Theme Update Test
|
||||
###################################
|
||||
|
||||
|
||||
def test_multi_waveform_widget_theme_update(qtbot, multi_waveform_widget):
|
||||
"""Test theme update for multi waveform widget."""
|
||||
qapp = QApplication.instance()
|
||||
|
||||
# Set the theme to dark
|
||||
set_theme("dark")
|
||||
palette = get_theme_palette()
|
||||
waveform_color_dark = multi_waveform_widget.waveform.plot_item.getAxis("left").pen().color()
|
||||
bg_color = multi_waveform_widget.fig.backgroundBrush().color()
|
||||
|
||||
assert bg_color == QColor(20, 20, 20)
|
||||
assert waveform_color_dark == palette.text().color()
|
||||
|
||||
# Set the theme to light
|
||||
set_theme("light")
|
||||
palette = get_theme_palette()
|
||||
waveform_color_light = multi_waveform_widget.waveform.plot_item.getAxis("left").pen().color()
|
||||
bg_color = multi_waveform_widget.fig.backgroundBrush().color()
|
||||
assert bg_color == QColor(233, 236, 239)
|
||||
assert waveform_color_light == palette.text().color()
|
||||
|
||||
assert waveform_color_dark != waveform_color_light
|
||||
|
||||
# Set the theme to auto and simulate OS theme change
|
||||
set_theme("auto")
|
||||
qapp.theme_signal.theme_updated.emit("dark")
|
||||
apply_theme("dark")
|
||||
|
||||
waveform_color = multi_waveform_widget.waveform.plot_item.getAxis("left").pen().color()
|
||||
bg_color = multi_waveform_widget.fig.backgroundBrush().color()
|
||||
assert bg_color == QColor(20, 20, 20)
|
||||
assert waveform_color == waveform_color_dark
|
Reference in New Issue
Block a user