bec-widgets 1.25.1__py3-none-any.whl → 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- .gitlab-ci.yml +3 -5
- CHANGELOG.md +631 -0
- PKG-INFO +3 -3
- bec_widgets/__init__.py +4 -0
- bec_widgets/applications/bw_launch.py +23 -0
- bec_widgets/applications/launch_window.py +430 -0
- bec_widgets/assets/app_icons/auto_update.png +0 -0
- bec_widgets/assets/app_icons/ui_loader_tile.png +0 -0
- bec_widgets/cli/__init__.py +0 -1
- bec_widgets/cli/client.py +1779 -2064
- bec_widgets/cli/client_utils.py +346 -174
- bec_widgets/cli/generate_cli.py +143 -37
- bec_widgets/cli/rpc/rpc_base.py +152 -21
- bec_widgets/cli/rpc/rpc_register.py +113 -6
- bec_widgets/cli/rpc/rpc_widget_handler.py +13 -11
- bec_widgets/cli/server.py +125 -239
- bec_widgets/examples/jupyter_console/jupyter_console_window.py +97 -145
- bec_widgets/examples/plugin_example_pyside/tictactoetaskmenu.py +1 -1
- bec_widgets/utils/bec_connector.py +190 -21
- bec_widgets/utils/bec_designer.py +7 -0
- bec_widgets/utils/bec_dispatcher.py +71 -4
- bec_widgets/utils/bec_plugin_helper.py +89 -0
- bec_widgets/utils/bec_signal_proxy.py +1 -1
- bec_widgets/utils/bec_widget.py +26 -10
- bec_widgets/utils/colors.py +1 -1
- bec_widgets/{qt_utils → utils}/compact_popup.py +2 -0
- bec_widgets/utils/container_utils.py +37 -12
- bec_widgets/utils/crosshair.py +25 -8
- bec_widgets/utils/entry_validator.py +3 -1
- bec_widgets/{qt_utils → utils}/error_popups.py +18 -0
- bec_widgets/{qt_utils → utils}/expandable_frame.py +2 -2
- bec_widgets/utils/forms_from_types/forms.py +182 -0
- bec_widgets/{widgets/editors/scan_metadata/_metadata_widgets.py → utils/forms_from_types/items.py} +41 -30
- bec_widgets/utils/generate_designer_plugin.py +40 -36
- bec_widgets/utils/linear_region_selector.py +2 -0
- bec_widgets/utils/name_utils.py +16 -0
- bec_widgets/{qt_utils → utils}/palette_viewer.py +2 -2
- bec_widgets/utils/plot_indicator_items.py +2 -5
- bec_widgets/utils/plugin_utils.py +47 -1
- bec_widgets/{qt_utils → utils}/round_frame.py +14 -14
- bec_widgets/utils/rpc_server.py +277 -0
- bec_widgets/utils/serialization.py +44 -0
- bec_widgets/{qt_utils → utils}/settings_dialog.py +26 -1
- bec_widgets/{qt_utils → utils}/side_panel.py +17 -10
- bec_widgets/{qt_utils → utils}/toolbar.py +69 -25
- bec_widgets/utils/ui_loader.py +8 -8
- bec_widgets/utils/widget_io.py +166 -25
- bec_widgets/widgets/containers/auto_update/auto_updates.py +364 -0
- bec_widgets/widgets/containers/dock/dock.py +157 -49
- bec_widgets/widgets/containers/dock/dock_area.py +186 -138
- bec_widgets/widgets/containers/layout_manager/layout_manager.py +2 -1
- bec_widgets/widgets/containers/main_window/addons/web_links.py +15 -0
- bec_widgets/widgets/containers/main_window/main_window.py +189 -41
- bec_widgets/widgets/control/buttons/button_abort/button_abort.py +3 -4
- bec_widgets/widgets/control/buttons/button_reset/button_reset.py +3 -4
- bec_widgets/widgets/control/buttons/button_resume/button_resume.py +3 -3
- bec_widgets/widgets/control/buttons/stop_button/stop_button.py +18 -7
- bec_widgets/widgets/control/device_control/position_indicator/position_indicator.py +22 -3
- bec_widgets/widgets/control/device_control/positioner_box/_base/positioner_box_base.py +31 -13
- bec_widgets/widgets/control/device_control/positioner_box/positioner_box/positioner_box.py +3 -1
- bec_widgets/widgets/control/device_control/positioner_box/positioner_box/positioner_box.ui +27 -4
- bec_widgets/widgets/control/device_control/positioner_box/positioner_box_2d/positioner_box_2d.py +5 -2
- bec_widgets/widgets/control/device_control/positioner_box/positioner_box_2d/positioner_box_2d.ui +97 -31
- bec_widgets/widgets/control/device_control/positioner_box/positioner_control_line/positioner_control_line.ui +11 -4
- bec_widgets/widgets/control/device_control/positioner_group/positioner_group.py +2 -3
- bec_widgets/widgets/control/device_input/base_classes/device_input_base.py +29 -4
- bec_widgets/widgets/control/device_input/base_classes/device_signal_input_base.py +1 -0
- bec_widgets/widgets/control/device_input/device_combobox/device_combobox.py +2 -2
- bec_widgets/widgets/control/device_input/device_line_edit/device_line_edit.py +2 -2
- bec_widgets/widgets/control/device_input/signal_combobox/signal_combobox.py +1 -2
- bec_widgets/widgets/control/device_input/signal_line_edit/signal_line_edit.py +1 -2
- bec_widgets/widgets/control/scan_control/scan_control.py +7 -5
- bec_widgets/widgets/control/scan_control/scan_group_box.py +28 -5
- bec_widgets/widgets/dap/dap_combo_box/dap_combo_box.py +1 -2
- bec_widgets/widgets/dap/lmfit_dialog/lmfit_dialog.py +3 -4
- bec_widgets/widgets/dap/lmfit_dialog/lmfit_dialog_vertical.ui +14 -8
- bec_widgets/widgets/editors/console/console.py +1 -1
- bec_widgets/widgets/editors/{scan_metadata/additional_metadata_table.py → dict_backed_table.py} +29 -6
- bec_widgets/widgets/editors/scan_metadata/__init__.py +0 -7
- bec_widgets/widgets/editors/scan_metadata/_util.py +1 -1
- bec_widgets/widgets/{plots/motor_map/register_bec_motor_map_widget.py → editors/scan_metadata/register_scan_metadata.py} +2 -4
- bec_widgets/widgets/editors/scan_metadata/scan_metadata.py +42 -136
- bec_widgets/widgets/editors/scan_metadata/scan_metadata.pyproject +1 -0
- bec_widgets/widgets/{plots/multi_waveform/bec_multi_waveform_widget_plugin.py → editors/scan_metadata/scan_metadata_plugin.py} +9 -9
- bec_widgets/widgets/editors/text_box/text_box.py +2 -3
- bec_widgets/widgets/editors/website/website.py +2 -2
- bec_widgets/widgets/games/minesweeper.py +3 -2
- bec_widgets/widgets/plots/image/image.py +960 -0
- bec_widgets/widgets/plots/image/image.pyproject +1 -0
- bec_widgets/widgets/plots/image/image_item.py +279 -0
- bec_widgets/widgets/plots/{motor_map/bec_motor_map_widget_plugin.py → image/image_plugin.py} +11 -13
- bec_widgets/widgets/{containers/figure/plots → plots}/image/image_processor.py +31 -64
- bec_widgets/widgets/plots/image/{register_bec_image_widget.py → register_image.py} +2 -2
- bec_widgets/widgets/plots/image/toolbar_bundles/image_selection.py +59 -0
- bec_widgets/widgets/plots/image/toolbar_bundles/processing.py +79 -0
- bec_widgets/widgets/plots/motor_map/motor_map.py +832 -0
- bec_widgets/widgets/plots/motor_map/motor_map.pyproject +1 -0
- bec_widgets/widgets/plots/motor_map/motor_map_plugin.py +54 -0
- bec_widgets/widgets/plots/{multi_waveform/register_bec_multi_waveform_widget.py → motor_map/register_motor_map.py} +2 -4
- bec_widgets/widgets/plots/motor_map/settings/motor_map_settings.py +129 -0
- bec_widgets/widgets/plots/motor_map/settings/motor_map_settings.ui +120 -0
- bec_widgets/widgets/plots/motor_map/toolbar_bundles/motor_selection.py +70 -0
- bec_widgets/widgets/plots/multi_waveform/multi_waveform.py +508 -0
- bec_widgets/widgets/plots/multi_waveform/multi_waveform.pyproject +1 -0
- bec_widgets/widgets/plots/multi_waveform/multi_waveform_plugin.py +54 -0
- bec_widgets/widgets/plots/multi_waveform/register_multi_waveform.py +15 -0
- bec_widgets/widgets/plots/multi_waveform/settings/control_panel.py +144 -0
- bec_widgets/widgets/plots/multi_waveform/settings/multi_waveform_controls.ui +164 -0
- bec_widgets/widgets/plots/multi_waveform/toolbar_bundles/monitor_selection.py +65 -0
- bec_widgets/widgets/{plots_next_gen → plots}/plot_base.py +321 -40
- bec_widgets/widgets/plots/{waveform/register_bec_waveform_widget.py → scatter_waveform/register_scatter_waveform.py} +3 -3
- bec_widgets/widgets/plots/scatter_waveform/scatter_curve.py +197 -0
- bec_widgets/widgets/plots/scatter_waveform/scatter_waveform.py +553 -0
- bec_widgets/widgets/plots/scatter_waveform/scatter_waveform.pyproject +1 -0
- bec_widgets/widgets/plots/{image/bec_image_widget_plugin.py → scatter_waveform/scatter_waveform_plugin.py} +9 -13
- bec_widgets/widgets/plots/scatter_waveform/settings/scatter_curve_setting.py +138 -0
- bec_widgets/widgets/plots/scatter_waveform/settings/scatter_curve_settings_horizontal.ui +195 -0
- bec_widgets/widgets/plots/scatter_waveform/settings/scatter_curve_settings_vertical.ui +204 -0
- bec_widgets/widgets/{plots_next_gen → plots}/setting_menus/axis_settings.py +8 -8
- bec_widgets/widgets/{plots_next_gen → plots}/toolbar_bundles/mouse_interactions.py +4 -18
- bec_widgets/widgets/{plots_next_gen → plots}/toolbar_bundles/plot_export.py +14 -3
- bec_widgets/widgets/{plots_next_gen → plots}/toolbar_bundles/roi_bundle.py +6 -1
- bec_widgets/widgets/{plots_next_gen → plots}/toolbar_bundles/save_state.py +2 -2
- bec_widgets/widgets/{containers/figure/plots/waveform/waveform_curve.py → plots/waveform/curve.py} +119 -49
- bec_widgets/widgets/plots/waveform/register_waveform.py +15 -0
- bec_widgets/widgets/plots/waveform/settings/curve_settings/curve_setting.py +125 -0
- bec_widgets/widgets/plots/waveform/settings/curve_settings/curve_tree.py +576 -0
- bec_widgets/widgets/plots/waveform/utils/__init__.py +0 -0
- bec_widgets/widgets/plots/waveform/utils/roi_manager.py +84 -0
- bec_widgets/widgets/plots/waveform/waveform.py +1794 -0
- bec_widgets/widgets/plots/waveform/waveform.pyproject +1 -0
- bec_widgets/widgets/plots/waveform/{bec_waveform_widget_plugin.py → waveform_plugin.py} +9 -13
- bec_widgets/widgets/progress/bec_progressbar/bec_progressbar.py +1 -2
- bec_widgets/widgets/progress/ring_progress_bar/ring.py +11 -10
- bec_widgets/widgets/progress/ring_progress_bar/ring_progress_bar.py +24 -14
- bec_widgets/widgets/services/bec_queue/bec_queue.py +13 -11
- bec_widgets/widgets/services/bec_status_box/bec_status_box.py +3 -4
- bec_widgets/widgets/services/device_browser/device_browser.py +5 -2
- bec_widgets/widgets/services/device_browser/device_item/device_item.py +1 -1
- bec_widgets/widgets/utility/logpanel/logpanel.py +36 -17
- bec_widgets/widgets/utility/spinbox/decimal_spinbox.py +3 -3
- bec_widgets/widgets/utility/visual/color_button/color_button.py +1 -1
- bec_widgets/widgets/utility/visual/colormap_widget/colormap_widget.py +4 -6
- bec_widgets/widgets/utility/visual/dark_mode_button/dark_mode_button.py +4 -8
- {bec_widgets-1.25.1.dist-info → bec_widgets-2.0.0.dist-info}/METADATA +3 -3
- {bec_widgets-1.25.1.dist-info → bec_widgets-2.0.0.dist-info}/RECORD +168 -153
- pyproject.toml +3 -3
- bec_widgets/applications/alignment/alignment_1d/alignment_1d.py +0 -198
- bec_widgets/applications/alignment/alignment_1d/alignment_1d.ui +0 -615
- bec_widgets/applications/bec_app.py +0 -84
- bec_widgets/cli/auto_updates.py +0 -168
- bec_widgets/widgets/containers/figure/__init__.py +0 -1
- bec_widgets/widgets/containers/figure/figure.py +0 -796
- bec_widgets/widgets/containers/figure/plots/axis_settings.py +0 -91
- bec_widgets/widgets/containers/figure/plots/axis_settings.ui +0 -256
- bec_widgets/widgets/containers/figure/plots/image/image.py +0 -772
- bec_widgets/widgets/containers/figure/plots/image/image_item.py +0 -337
- bec_widgets/widgets/containers/figure/plots/motor_map/motor_map.py +0 -525
- bec_widgets/widgets/containers/figure/plots/multi_waveform/multi_waveform.py +0 -340
- bec_widgets/widgets/containers/figure/plots/plot_base.py +0 -505
- bec_widgets/widgets/containers/figure/plots/waveform/waveform.py +0 -1563
- bec_widgets/widgets/plots/image/bec_image_widget.pyproject +0 -1
- bec_widgets/widgets/plots/image/image_widget.py +0 -515
- bec_widgets/widgets/plots/motor_map/bec_motor_map_widget.pyproject +0 -1
- bec_widgets/widgets/plots/motor_map/motor_map_dialog/motor_map_settings.py +0 -56
- bec_widgets/widgets/plots/motor_map/motor_map_dialog/motor_map_settings.ui +0 -108
- bec_widgets/widgets/plots/motor_map/motor_map_widget.py +0 -234
- bec_widgets/widgets/plots/multi_waveform/bec_multi_waveform_widget.pyproject +0 -1
- bec_widgets/widgets/plots/multi_waveform/multi_waveform_controls.ui +0 -99
- bec_widgets/widgets/plots/multi_waveform/multi_waveform_widget.py +0 -536
- bec_widgets/widgets/plots/waveform/bec_waveform_widget.pyproject +0 -1
- bec_widgets/widgets/plots/waveform/waveform_popups/curve_dialog/curve_dialog.py +0 -336
- bec_widgets/widgets/plots/waveform/waveform_popups/curve_dialog/curve_dialog.ui +0 -372
- bec_widgets/widgets/plots/waveform/waveform_popups/dap_summary_dialog/dap_summary_dialog.py +0 -25
- bec_widgets/widgets/plots/waveform/waveform_widget.py +0 -751
- /bec_widgets/{qt_utils → utils}/collapsible_panel_manager.py +0 -0
- /bec_widgets/{applications/alignment → utils/forms_from_types}/__init__.py +0 -0
- /bec_widgets/{qt_utils → utils}/redis_message_waiter.py +0 -0
- /bec_widgets/{applications/alignment/alignment_1d → widgets/containers/auto_update}/__init__.py +0 -0
- /bec_widgets/{qt_utils → widgets/containers/main_window/addons}/__init__.py +0 -0
- /bec_widgets/widgets/{containers/figure/plots → plots/image/toolbar_bundles}/__init__.py +0 -0
- /bec_widgets/widgets/{containers/figure/plots/image → plots/motor_map/settings}/__init__.py +0 -0
- /bec_widgets/widgets/{containers/figure/plots/motor_map → plots/motor_map/toolbar_bundles}/__init__.py +0 -0
- /bec_widgets/widgets/{containers/figure/plots/multi_waveform → plots/multi_waveform/settings}/__init__.py +0 -0
- /bec_widgets/widgets/{containers/figure/plots/waveform → plots/multi_waveform/toolbar_bundles}/__init__.py +0 -0
- /bec_widgets/widgets/plots/{motor_map/motor_map_dialog → scatter_waveform}/__init__.py +0 -0
- /bec_widgets/widgets/plots/{waveform/waveform_popups → scatter_waveform/settings}/__init__.py +0 -0
- /bec_widgets/widgets/plots/{waveform/waveform_popups/curve_dialog → setting_menus}/__init__.py +0 -0
- /bec_widgets/widgets/{plots_next_gen → plots}/setting_menus/axis_settings_horizontal.ui +0 -0
- /bec_widgets/widgets/{plots_next_gen → plots}/setting_menus/axis_settings_vertical.ui +0 -0
- /bec_widgets/widgets/plots/{waveform/waveform_popups/dap_summary_dialog → toolbar_bundles}/__init__.py +0 -0
- /bec_widgets/widgets/{plots_next_gen/setting_menus → plots/waveform/settings}/__init__.py +0 -0
- /bec_widgets/widgets/{plots_next_gen/toolbar_bundles → plots/waveform/settings/curve_settings}/__init__.py +0 -0
- {bec_widgets-1.25.1.dist-info → bec_widgets-2.0.0.dist-info}/WHEEL +0 -0
- {bec_widgets-1.25.1.dist-info → bec_widgets-2.0.0.dist-info}/entry_points.txt +0 -0
- {bec_widgets-1.25.1.dist-info → bec_widgets-2.0.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,536 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
from typing import Literal
|
3
|
-
|
4
|
-
import pyqtgraph as pg
|
5
|
-
from bec_lib.device import ReadoutPriority
|
6
|
-
from bec_lib.logger import bec_logger
|
7
|
-
from qtpy.QtCore import Slot
|
8
|
-
from qtpy.QtWidgets import QVBoxLayout, QWidget
|
9
|
-
|
10
|
-
from bec_widgets.qt_utils.error_popups import SafeSlot
|
11
|
-
from bec_widgets.qt_utils.settings_dialog import SettingsDialog
|
12
|
-
from bec_widgets.qt_utils.toolbar import (
|
13
|
-
DeviceSelectionAction,
|
14
|
-
MaterialIconAction,
|
15
|
-
ModularToolBar,
|
16
|
-
SeparatorAction,
|
17
|
-
WidgetAction,
|
18
|
-
)
|
19
|
-
from bec_widgets.utils import UILoader
|
20
|
-
from bec_widgets.utils.bec_widget import BECWidget
|
21
|
-
from bec_widgets.widgets.containers.figure import BECFigure
|
22
|
-
from bec_widgets.widgets.containers.figure.plots.axis_settings import AxisSettings
|
23
|
-
from bec_widgets.widgets.containers.figure.plots.multi_waveform.multi_waveform import (
|
24
|
-
BECMultiWaveformConfig,
|
25
|
-
)
|
26
|
-
from bec_widgets.widgets.control.device_input.base_classes.device_input_base import BECDeviceFilter
|
27
|
-
from bec_widgets.widgets.control.device_input.device_combobox.device_combobox import DeviceComboBox
|
28
|
-
from bec_widgets.widgets.utility.visual.colormap_widget.colormap_widget import BECColorMapWidget
|
29
|
-
|
30
|
-
logger = bec_logger.logger
|
31
|
-
|
32
|
-
|
33
|
-
class BECMultiWaveformWidget(BECWidget, QWidget):
|
34
|
-
PLUGIN = True
|
35
|
-
ICON_NAME = "ssid_chart"
|
36
|
-
USER_ACCESS = [
|
37
|
-
"curves",
|
38
|
-
"set_monitor",
|
39
|
-
"set_curve_highlight",
|
40
|
-
"set_opacity",
|
41
|
-
"set_curve_limit",
|
42
|
-
"set_buffer_flush",
|
43
|
-
"set_highlight_last_curve",
|
44
|
-
"set_colormap",
|
45
|
-
"set",
|
46
|
-
"set_title",
|
47
|
-
"set_x_label",
|
48
|
-
"set_y_label",
|
49
|
-
"set_x_scale",
|
50
|
-
"set_y_scale",
|
51
|
-
"set_x_lim",
|
52
|
-
"set_y_lim",
|
53
|
-
"set_grid",
|
54
|
-
"set_colormap",
|
55
|
-
"enable_fps_monitor",
|
56
|
-
"lock_aspect_ratio",
|
57
|
-
"export",
|
58
|
-
]
|
59
|
-
|
60
|
-
def __init__(
|
61
|
-
self,
|
62
|
-
parent: QWidget | None = None,
|
63
|
-
config: BECMultiWaveformConfig | dict = None,
|
64
|
-
client=None,
|
65
|
-
gui_id: str | None = None,
|
66
|
-
**kwargs,
|
67
|
-
) -> None:
|
68
|
-
if config is None:
|
69
|
-
config = BECMultiWaveformConfig(widget_class=self.__class__.__name__)
|
70
|
-
else:
|
71
|
-
if isinstance(config, dict):
|
72
|
-
config = BECMultiWaveformConfig(**config)
|
73
|
-
super().__init__(client=client, gui_id=gui_id, **kwargs)
|
74
|
-
QWidget.__init__(self, parent)
|
75
|
-
|
76
|
-
self.layout = QVBoxLayout(self)
|
77
|
-
self.layout.setSpacing(0)
|
78
|
-
self.layout.setContentsMargins(0, 0, 0, 0)
|
79
|
-
|
80
|
-
self.fig = BECFigure()
|
81
|
-
self.colormap_button = BECColorMapWidget(cmap="magma")
|
82
|
-
self.toolbar = ModularToolBar(
|
83
|
-
actions={
|
84
|
-
"monitor": DeviceSelectionAction(
|
85
|
-
"",
|
86
|
-
DeviceComboBox(
|
87
|
-
device_filter=BECDeviceFilter.DEVICE,
|
88
|
-
readout_priority_filter=ReadoutPriority.ASYNC,
|
89
|
-
),
|
90
|
-
),
|
91
|
-
"connect": MaterialIconAction(icon_name="link", tooltip="Connect Device"),
|
92
|
-
"separator_0": SeparatorAction(),
|
93
|
-
"colormap": WidgetAction(widget=self.colormap_button),
|
94
|
-
"separator_1": SeparatorAction(),
|
95
|
-
"save": MaterialIconAction(icon_name="save", tooltip="Open Export Dialog"),
|
96
|
-
"matplotlib": MaterialIconAction(
|
97
|
-
icon_name="photo_library", tooltip="Open Matplotlib Plot"
|
98
|
-
),
|
99
|
-
"separator_2": SeparatorAction(),
|
100
|
-
"drag_mode": MaterialIconAction(
|
101
|
-
icon_name="drag_pan", tooltip="Drag Mouse Mode", checkable=True
|
102
|
-
),
|
103
|
-
"rectangle_mode": MaterialIconAction(
|
104
|
-
icon_name="frame_inspect", tooltip="Rectangle Zoom Mode", checkable=True
|
105
|
-
),
|
106
|
-
"auto_range": MaterialIconAction(
|
107
|
-
icon_name="open_in_full", tooltip="Autorange Plot"
|
108
|
-
),
|
109
|
-
"crosshair": MaterialIconAction(
|
110
|
-
icon_name="point_scan", tooltip="Show Crosshair", checkable=True
|
111
|
-
),
|
112
|
-
"separator_3": SeparatorAction(),
|
113
|
-
"fps_monitor": MaterialIconAction(
|
114
|
-
icon_name="speed", tooltip="Show FPS Monitor", checkable=True
|
115
|
-
),
|
116
|
-
"axis_settings": MaterialIconAction(
|
117
|
-
icon_name="settings", tooltip="Open Configuration Dialog"
|
118
|
-
),
|
119
|
-
},
|
120
|
-
target_widget=self,
|
121
|
-
)
|
122
|
-
|
123
|
-
self.layout.addWidget(self.toolbar)
|
124
|
-
self.layout.addWidget(self.fig)
|
125
|
-
|
126
|
-
self.waveform = self.fig.multi_waveform() # FIXME config should be injected here
|
127
|
-
self.config = config
|
128
|
-
|
129
|
-
self.create_multi_waveform_controls()
|
130
|
-
|
131
|
-
self._hook_actions()
|
132
|
-
self.waveform.monitor_signal_updated.connect(self.update_controls_limits)
|
133
|
-
|
134
|
-
def create_multi_waveform_controls(self):
|
135
|
-
"""
|
136
|
-
Create the controls for the multi waveform widget.
|
137
|
-
"""
|
138
|
-
current_path = os.path.dirname(__file__)
|
139
|
-
self.controls = UILoader(self).loader(
|
140
|
-
os.path.join(current_path, "multi_waveform_controls.ui")
|
141
|
-
)
|
142
|
-
self.layout.addWidget(self.controls)
|
143
|
-
|
144
|
-
# Hook default controls properties
|
145
|
-
self.controls.checkbox_highlight.setChecked(self.config.highlight_last_curve)
|
146
|
-
self.controls.spinbox_opacity.setValue(self.config.opacity)
|
147
|
-
self.controls.slider_opacity.setValue(self.config.opacity)
|
148
|
-
self.controls.spinbox_max_trace.setValue(self.config.curve_limit)
|
149
|
-
self.controls.checkbox_flush_buffer.setChecked(self.config.flush_buffer)
|
150
|
-
|
151
|
-
# Connect signals
|
152
|
-
self.controls.spinbox_max_trace.valueChanged.connect(self.set_curve_limit)
|
153
|
-
self.controls.checkbox_flush_buffer.toggled.connect(self.set_buffer_flush)
|
154
|
-
self.controls.slider_opacity.valueChanged.connect(self.controls.spinbox_opacity.setValue)
|
155
|
-
self.controls.spinbox_opacity.valueChanged.connect(self.controls.slider_opacity.setValue)
|
156
|
-
self.controls.slider_opacity.valueChanged.connect(self.set_opacity)
|
157
|
-
self.controls.spinbox_opacity.valueChanged.connect(self.set_opacity)
|
158
|
-
self.controls.slider_index.valueChanged.connect(self.controls.spinbox_index.setValue)
|
159
|
-
self.controls.spinbox_index.valueChanged.connect(self.controls.slider_index.setValue)
|
160
|
-
self.controls.slider_index.valueChanged.connect(self.set_curve_highlight)
|
161
|
-
self.controls.spinbox_index.valueChanged.connect(self.set_curve_highlight)
|
162
|
-
self.controls.checkbox_highlight.toggled.connect(self.set_highlight_last_curve)
|
163
|
-
|
164
|
-
# Trigger first round of settings
|
165
|
-
self.set_curve_limit(self.config.curve_limit)
|
166
|
-
self.set_opacity(self.config.opacity)
|
167
|
-
self.set_highlight_last_curve(self.config.highlight_last_curve)
|
168
|
-
|
169
|
-
@Slot()
|
170
|
-
def update_controls_limits(self):
|
171
|
-
"""
|
172
|
-
Update the limits of the controls.
|
173
|
-
"""
|
174
|
-
num_curves = len(self.waveform.curves)
|
175
|
-
if num_curves == 0:
|
176
|
-
num_curves = 1 # Avoid setting max to 0
|
177
|
-
current_index = num_curves - 1
|
178
|
-
self.controls.slider_index.setMinimum(0)
|
179
|
-
self.controls.slider_index.setMaximum(self.waveform.number_of_visible_curves - 1)
|
180
|
-
self.controls.spinbox_index.setMaximum(self.waveform.number_of_visible_curves - 1)
|
181
|
-
if self.controls.checkbox_highlight.isChecked():
|
182
|
-
self.controls.slider_index.setValue(current_index)
|
183
|
-
self.controls.spinbox_index.setValue(current_index)
|
184
|
-
|
185
|
-
def _hook_actions(self):
|
186
|
-
self.toolbar.widgets["connect"].action.triggered.connect(self._connect_action)
|
187
|
-
# Separator 0
|
188
|
-
self.toolbar.widgets["save"].action.triggered.connect(self.export)
|
189
|
-
self.toolbar.widgets["matplotlib"].action.triggered.connect(self.export_to_matplotlib)
|
190
|
-
self.toolbar.widgets["colormap"].widget.colormap_changed_signal.connect(self.set_colormap)
|
191
|
-
# Separator 1
|
192
|
-
self.toolbar.widgets["drag_mode"].action.triggered.connect(self.enable_mouse_pan_mode)
|
193
|
-
self.toolbar.widgets["rectangle_mode"].action.triggered.connect(
|
194
|
-
self.enable_mouse_rectangle_mode
|
195
|
-
)
|
196
|
-
self.toolbar.widgets["auto_range"].action.triggered.connect(self._auto_range_from_toolbar)
|
197
|
-
self.toolbar.widgets["crosshair"].action.triggered.connect(self.waveform.toggle_crosshair)
|
198
|
-
# Separator 2
|
199
|
-
self.toolbar.widgets["fps_monitor"].action.triggered.connect(self.enable_fps_monitor)
|
200
|
-
self.toolbar.widgets["axis_settings"].action.triggered.connect(self.show_axis_settings)
|
201
|
-
|
202
|
-
###################################
|
203
|
-
# Dialog Windows
|
204
|
-
###################################
|
205
|
-
@SafeSlot(popup_error=True)
|
206
|
-
def _connect_action(self):
|
207
|
-
monitor_combo = self.toolbar.widgets["monitor"].device_combobox
|
208
|
-
monitor_name = monitor_combo.currentText()
|
209
|
-
self.set_monitor(monitor=monitor_name)
|
210
|
-
monitor_combo.setStyleSheet("QComboBox { background-color: " "; }")
|
211
|
-
|
212
|
-
def show_axis_settings(self):
|
213
|
-
dialog = SettingsDialog(
|
214
|
-
self,
|
215
|
-
settings_widget=AxisSettings(),
|
216
|
-
window_title="Axis Settings",
|
217
|
-
config=self.waveform._config_dict["axis"],
|
218
|
-
)
|
219
|
-
dialog.exec()
|
220
|
-
|
221
|
-
########################################
|
222
|
-
# User Access Methods from MultiWaveform
|
223
|
-
########################################
|
224
|
-
@property
|
225
|
-
def curves(self) -> list[pg.PlotDataItem]:
|
226
|
-
"""
|
227
|
-
Get the curves of the plot widget as a list
|
228
|
-
Returns:
|
229
|
-
list: List of curves.
|
230
|
-
"""
|
231
|
-
return list(self.waveform.curves)
|
232
|
-
|
233
|
-
@curves.setter
|
234
|
-
def curves(self, value: list[pg.PlotDataItem]):
|
235
|
-
self.waveform.curves = value
|
236
|
-
|
237
|
-
@SafeSlot(popup_error=True)
|
238
|
-
def set_monitor(self, monitor: str) -> None:
|
239
|
-
"""
|
240
|
-
Set the monitor of the plot widget.
|
241
|
-
|
242
|
-
Args:
|
243
|
-
monitor(str): The monitor to set.
|
244
|
-
"""
|
245
|
-
self.waveform.set_monitor(monitor)
|
246
|
-
if self.toolbar.widgets["monitor"].device_combobox.currentText() != monitor:
|
247
|
-
self.toolbar.widgets["monitor"].device_combobox.setCurrentText(monitor)
|
248
|
-
self.toolbar.widgets["monitor"].device_combobox.setStyleSheet(
|
249
|
-
"QComboBox { background-color: " "; }"
|
250
|
-
)
|
251
|
-
|
252
|
-
@SafeSlot(int)
|
253
|
-
def set_curve_highlight(self, index: int) -> None:
|
254
|
-
"""
|
255
|
-
Set the curve highlight of the plot widget by index
|
256
|
-
|
257
|
-
Args:
|
258
|
-
index(int): The index of the curve to highlight.
|
259
|
-
"""
|
260
|
-
if self.controls.checkbox_highlight.isChecked():
|
261
|
-
# If always highlighting the last curve, set index to -1
|
262
|
-
self.waveform.set_curve_highlight(-1)
|
263
|
-
else:
|
264
|
-
self.waveform.set_curve_highlight(index)
|
265
|
-
|
266
|
-
@SafeSlot(int)
|
267
|
-
def set_opacity(self, opacity: int) -> None:
|
268
|
-
"""
|
269
|
-
Set the opacity of the plot widget.
|
270
|
-
|
271
|
-
Args:
|
272
|
-
opacity(int): The opacity to set.
|
273
|
-
"""
|
274
|
-
self.waveform.set_opacity(opacity)
|
275
|
-
|
276
|
-
@SafeSlot(int)
|
277
|
-
def set_curve_limit(self, curve_limit: int) -> None:
|
278
|
-
"""
|
279
|
-
Set the maximum number of traces to display on the plot widget.
|
280
|
-
|
281
|
-
Args:
|
282
|
-
curve_limit(int): The maximum number of traces to display.
|
283
|
-
"""
|
284
|
-
flush_buffer = self.controls.checkbox_flush_buffer.isChecked()
|
285
|
-
self.waveform.set_curve_limit(curve_limit, flush_buffer)
|
286
|
-
self.update_controls_limits()
|
287
|
-
|
288
|
-
@SafeSlot(bool)
|
289
|
-
def set_buffer_flush(self, flush_buffer: bool) -> None:
|
290
|
-
"""
|
291
|
-
Set the buffer flush property of the plot widget.
|
292
|
-
|
293
|
-
Args:
|
294
|
-
flush_buffer(bool): True to flush the buffer, False to not flush the buffer.
|
295
|
-
"""
|
296
|
-
curve_limit = self.controls.spinbox_max_trace.value()
|
297
|
-
self.waveform.set_curve_limit(curve_limit, flush_buffer)
|
298
|
-
self.update_controls_limits()
|
299
|
-
|
300
|
-
@SafeSlot(bool)
|
301
|
-
def set_highlight_last_curve(self, enable: bool) -> None:
|
302
|
-
"""
|
303
|
-
Enable or disable highlighting of the last curve.
|
304
|
-
|
305
|
-
Args:
|
306
|
-
enable(bool): True to enable highlighting of the last curve, False to disable.
|
307
|
-
"""
|
308
|
-
self.waveform.config.highlight_last_curve = enable
|
309
|
-
if enable:
|
310
|
-
self.controls.slider_index.setEnabled(False)
|
311
|
-
self.controls.spinbox_index.setEnabled(False)
|
312
|
-
self.controls.checkbox_highlight.setChecked(True)
|
313
|
-
self.waveform.set_curve_highlight(-1)
|
314
|
-
else:
|
315
|
-
self.controls.slider_index.setEnabled(True)
|
316
|
-
self.controls.spinbox_index.setEnabled(True)
|
317
|
-
self.controls.checkbox_highlight.setChecked(False)
|
318
|
-
index = self.controls.spinbox_index.value()
|
319
|
-
self.waveform.set_curve_highlight(index)
|
320
|
-
|
321
|
-
@SafeSlot()
|
322
|
-
def set_colormap(self, colormap: str) -> None:
|
323
|
-
"""
|
324
|
-
Set the colormap of the plot widget.
|
325
|
-
|
326
|
-
Args:
|
327
|
-
colormap(str): The colormap to set.
|
328
|
-
"""
|
329
|
-
self.waveform.set_colormap(colormap)
|
330
|
-
|
331
|
-
###################################
|
332
|
-
# User Access Methods from PlotBase
|
333
|
-
###################################
|
334
|
-
def set(self, **kwargs):
|
335
|
-
"""
|
336
|
-
Set the properties of the plot widget.
|
337
|
-
|
338
|
-
Args:
|
339
|
-
**kwargs: Keyword arguments for the properties to be set.
|
340
|
-
|
341
|
-
Possible properties:
|
342
|
-
- title: str
|
343
|
-
- x_label: str
|
344
|
-
- y_label: str
|
345
|
-
- x_scale: Literal["linear", "log"]
|
346
|
-
- y_scale: Literal["linear", "log"]
|
347
|
-
- x_lim: tuple
|
348
|
-
- y_lim: tuple
|
349
|
-
- legend_label_size: int
|
350
|
-
"""
|
351
|
-
self.waveform.set(**kwargs)
|
352
|
-
|
353
|
-
def set_title(self, title: str):
|
354
|
-
"""
|
355
|
-
Set the title of the plot widget.
|
356
|
-
|
357
|
-
Args:
|
358
|
-
title(str): The title to set.
|
359
|
-
"""
|
360
|
-
self.waveform.set_title(title)
|
361
|
-
|
362
|
-
def set_x_label(self, x_label: str):
|
363
|
-
"""
|
364
|
-
Set the x-axis label of the plot widget.
|
365
|
-
|
366
|
-
Args:
|
367
|
-
x_label(str): The x-axis label to set.
|
368
|
-
"""
|
369
|
-
self.waveform.set_x_label(x_label)
|
370
|
-
|
371
|
-
def set_y_label(self, y_label: str):
|
372
|
-
"""
|
373
|
-
Set the y-axis label of the plot widget.
|
374
|
-
|
375
|
-
Args:
|
376
|
-
y_label(str): The y-axis label to set.
|
377
|
-
"""
|
378
|
-
self.waveform.set_y_label(y_label)
|
379
|
-
|
380
|
-
def set_x_scale(self, x_scale: Literal["linear", "log"]):
|
381
|
-
"""
|
382
|
-
Set the x-axis scale of the plot widget.
|
383
|
-
|
384
|
-
Args:
|
385
|
-
x_scale(str): The x-axis scale to set.
|
386
|
-
"""
|
387
|
-
self.waveform.set_x_scale(x_scale)
|
388
|
-
|
389
|
-
def set_y_scale(self, y_scale: Literal["linear", "log"]):
|
390
|
-
"""
|
391
|
-
Set the y-axis scale of the plot widget.
|
392
|
-
|
393
|
-
Args:
|
394
|
-
y_scale(str): The y-axis scale to set.
|
395
|
-
"""
|
396
|
-
self.waveform.set_y_scale(y_scale)
|
397
|
-
|
398
|
-
def set_x_lim(self, x_lim: tuple):
|
399
|
-
"""
|
400
|
-
Set x-axis limits of the plot widget.
|
401
|
-
|
402
|
-
Args:
|
403
|
-
x_lim(tuple): The x-axis limits to set.
|
404
|
-
"""
|
405
|
-
self.waveform.set_x_lim(x_lim)
|
406
|
-
|
407
|
-
def set_y_lim(self, y_lim: tuple):
|
408
|
-
"""
|
409
|
-
Set y-axis limits of the plot widget.
|
410
|
-
|
411
|
-
Args:
|
412
|
-
y_lim(tuple): The y-axis limits to set.
|
413
|
-
"""
|
414
|
-
self.waveform.set_y_lim(y_lim)
|
415
|
-
|
416
|
-
def set_legend_label_size(self, legend_label_size: int):
|
417
|
-
"""
|
418
|
-
Set the legend label size of the plot widget.
|
419
|
-
|
420
|
-
Args:
|
421
|
-
legend_label_size(int): The legend label size to set.
|
422
|
-
"""
|
423
|
-
self.waveform.set_legend_label_size(legend_label_size)
|
424
|
-
|
425
|
-
def set_auto_range(self, enabled: bool, axis: str = "xy"):
|
426
|
-
"""
|
427
|
-
Set the auto range of the plot widget.
|
428
|
-
|
429
|
-
Args:
|
430
|
-
enabled(bool): True to enable auto range, False to disable.
|
431
|
-
axis(str): The axis to set the auto range for. Default is "xy".
|
432
|
-
"""
|
433
|
-
self.waveform.set_auto_range(enabled, axis)
|
434
|
-
|
435
|
-
def enable_fps_monitor(self, enabled: bool):
|
436
|
-
"""
|
437
|
-
Enable or disable the FPS monitor
|
438
|
-
|
439
|
-
Args:
|
440
|
-
enabled(bool): True to enable the FPS monitor, False to disable.
|
441
|
-
"""
|
442
|
-
self.waveform.enable_fps_monitor(enabled)
|
443
|
-
if self.toolbar.widgets["fps_monitor"].action.isChecked() != enabled:
|
444
|
-
self.toolbar.widgets["fps_monitor"].action.setChecked(enabled)
|
445
|
-
|
446
|
-
@SafeSlot()
|
447
|
-
def _auto_range_from_toolbar(self):
|
448
|
-
"""
|
449
|
-
Set the auto range of the plot widget from the toolbar.
|
450
|
-
"""
|
451
|
-
self.waveform.set_auto_range(True, "xy")
|
452
|
-
|
453
|
-
def set_grid(self, x_grid: bool, y_grid: bool):
|
454
|
-
"""
|
455
|
-
Set the grid of the plot widget.
|
456
|
-
|
457
|
-
Args:
|
458
|
-
x_grid(bool): True to enable the x-grid, False to disable.
|
459
|
-
y_grid(bool): True to enable the y-grid, False to disable.
|
460
|
-
"""
|
461
|
-
self.waveform.set_grid(x_grid, y_grid)
|
462
|
-
|
463
|
-
def set_outer_axes(self, show: bool):
|
464
|
-
"""
|
465
|
-
Set the outer axes of the plot widget.
|
466
|
-
|
467
|
-
Args:
|
468
|
-
show(bool): True to show the outer axes, False to hide.
|
469
|
-
"""
|
470
|
-
self.waveform.set_outer_axes(show)
|
471
|
-
|
472
|
-
def lock_aspect_ratio(self, lock: bool):
|
473
|
-
"""
|
474
|
-
Lock the aspect ratio of the plot widget.
|
475
|
-
|
476
|
-
Args:
|
477
|
-
lock(bool): True to lock the aspect ratio, False to unlock.
|
478
|
-
"""
|
479
|
-
self.waveform.lock_aspect_ratio(lock)
|
480
|
-
|
481
|
-
@SafeSlot()
|
482
|
-
def enable_mouse_rectangle_mode(self):
|
483
|
-
"""
|
484
|
-
Enable the mouse rectangle mode of the plot widget.
|
485
|
-
"""
|
486
|
-
self.toolbar.widgets["rectangle_mode"].action.setChecked(True)
|
487
|
-
self.toolbar.widgets["drag_mode"].action.setChecked(False)
|
488
|
-
self.waveform.plot_item.getViewBox().setMouseMode(pg.ViewBox.RectMode)
|
489
|
-
|
490
|
-
@SafeSlot()
|
491
|
-
def enable_mouse_pan_mode(self):
|
492
|
-
"""
|
493
|
-
Enable the mouse pan mode of the plot widget.
|
494
|
-
"""
|
495
|
-
self.toolbar.widgets["drag_mode"].action.setChecked(True)
|
496
|
-
self.toolbar.widgets["rectangle_mode"].action.setChecked(False)
|
497
|
-
self.waveform.plot_item.getViewBox().setMouseMode(pg.ViewBox.PanMode)
|
498
|
-
|
499
|
-
def export(self):
|
500
|
-
"""
|
501
|
-
Export the plot widget.
|
502
|
-
"""
|
503
|
-
self.waveform.export()
|
504
|
-
|
505
|
-
def export_to_matplotlib(self):
|
506
|
-
"""
|
507
|
-
Export the plot widget to matplotlib.
|
508
|
-
"""
|
509
|
-
try:
|
510
|
-
import matplotlib as mpl
|
511
|
-
except ImportError:
|
512
|
-
self.warning_util.show_warning(
|
513
|
-
title="Matplotlib not installed",
|
514
|
-
message="Matplotlib is required for this feature.",
|
515
|
-
detailed_text="Please install matplotlib in your Python environment by using 'pip install matplotlib'.",
|
516
|
-
)
|
517
|
-
return
|
518
|
-
self.waveform.export_to_matplotlib()
|
519
|
-
|
520
|
-
#######################################
|
521
|
-
# User Access Methods from BECConnector
|
522
|
-
######################################
|
523
|
-
def cleanup(self):
|
524
|
-
self.fig.cleanup()
|
525
|
-
return super().cleanup()
|
526
|
-
|
527
|
-
|
528
|
-
if __name__ == "__main__": # pragma: no cover
|
529
|
-
import sys
|
530
|
-
|
531
|
-
from qtpy.QtWidgets import QApplication
|
532
|
-
|
533
|
-
app = QApplication(sys.argv)
|
534
|
-
widget = BECMultiWaveformWidget()
|
535
|
-
widget.show()
|
536
|
-
sys.exit(app.exec())
|
@@ -1 +0,0 @@
|
|
1
|
-
{'files': ['waveform_widget.py']}
|