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,41 +1,189 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
from
|
4
|
-
from
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
1
|
+
import os
|
2
|
+
|
3
|
+
from qtpy.QtCore import QSize
|
4
|
+
from qtpy.QtGui import QAction, QActionGroup, QIcon
|
5
|
+
from qtpy.QtWidgets import QApplication, QMainWindow, QStyle
|
6
|
+
|
7
|
+
import bec_widgets
|
8
|
+
from bec_widgets.utils import UILoader
|
9
|
+
from bec_widgets.utils.bec_widget import BECWidget
|
10
|
+
from bec_widgets.utils.colors import apply_theme
|
11
|
+
from bec_widgets.utils.container_utils import WidgetContainerUtils
|
12
|
+
from bec_widgets.utils.error_popups import SafeSlot
|
13
|
+
from bec_widgets.utils.widget_io import WidgetHierarchy
|
14
|
+
from bec_widgets.widgets.containers.main_window.addons.web_links import BECWebLinksMixin
|
15
|
+
|
16
|
+
MODULE_PATH = os.path.dirname(bec_widgets.__file__)
|
17
|
+
|
18
|
+
|
19
|
+
class BECMainWindow(BECWidget, QMainWindow):
|
20
|
+
RPC = False
|
21
|
+
PLUGIN = False
|
22
|
+
|
23
|
+
def __init__(
|
24
|
+
self,
|
25
|
+
parent=None,
|
26
|
+
gui_id: str = None,
|
27
|
+
client=None,
|
28
|
+
window_title: str = "BEC",
|
29
|
+
*args,
|
30
|
+
**kwargs,
|
31
|
+
):
|
32
|
+
super().__init__(parent=parent, gui_id=gui_id, **kwargs)
|
33
|
+
|
34
|
+
self.app = QApplication.instance()
|
35
|
+
self.setWindowTitle(window_title)
|
36
|
+
self._init_ui()
|
37
|
+
self._connect_to_theme_change()
|
38
|
+
|
39
|
+
def _init_ui(self):
|
40
|
+
|
41
|
+
# Set the icon
|
42
|
+
self._init_bec_icon()
|
43
|
+
|
44
|
+
# Set Menu and Status bar
|
45
|
+
self._setup_menu_bar()
|
46
|
+
|
47
|
+
# BEC Specific UI
|
48
|
+
self.display_app_id()
|
49
|
+
|
50
|
+
def _init_bec_icon(self):
|
51
|
+
icon = self.app.windowIcon()
|
52
|
+
if icon.isNull():
|
53
|
+
print("No icon is set, setting default icon")
|
54
|
+
icon = QIcon()
|
55
|
+
icon.addFile(
|
56
|
+
os.path.join(MODULE_PATH, "assets", "app_icons", "bec_widgets_icon.png"),
|
57
|
+
size=QSize(48, 48),
|
58
|
+
)
|
59
|
+
self.app.setWindowIcon(icon)
|
60
|
+
else:
|
61
|
+
print("An icon is set")
|
62
|
+
|
63
|
+
def load_ui(self, ui_file):
|
64
|
+
loader = UILoader(self)
|
65
|
+
self.ui = loader.loader(ui_file)
|
66
|
+
self.setCentralWidget(self.ui)
|
67
|
+
|
68
|
+
def display_app_id(self):
|
69
|
+
"""
|
70
|
+
Display the app ID in the status bar.
|
71
|
+
"""
|
72
|
+
if self.bec_dispatcher.cli_server is None:
|
73
|
+
status_message = "Not connected"
|
74
|
+
else:
|
75
|
+
# Get the server ID from the dispatcher
|
76
|
+
server_id = self.bec_dispatcher.cli_server.gui_id
|
77
|
+
status_message = f"App ID: {server_id}"
|
78
|
+
self.statusBar().showMessage(status_message)
|
79
|
+
|
80
|
+
def _fetch_theme(self) -> str:
|
81
|
+
return self.app.theme.theme
|
82
|
+
|
83
|
+
def _get_launcher_from_qapp(self):
|
84
|
+
"""
|
85
|
+
Get the launcher from the QApplication instance.
|
86
|
+
"""
|
87
|
+
from bec_widgets.applications.launch_window import LaunchWindow
|
88
|
+
|
89
|
+
qapp = QApplication.instance()
|
90
|
+
widgets = qapp.topLevelWidgets()
|
91
|
+
widgets = [w for w in widgets if isinstance(w, LaunchWindow)]
|
92
|
+
if widgets:
|
93
|
+
return widgets[0]
|
94
|
+
return None
|
95
|
+
|
96
|
+
def _show_launcher(self):
|
97
|
+
"""
|
98
|
+
Show the launcher if it exists.
|
99
|
+
"""
|
100
|
+
launcher = self._get_launcher_from_qapp()
|
101
|
+
if launcher:
|
102
|
+
launcher.show()
|
103
|
+
launcher.activateWindow()
|
104
|
+
launcher.raise_()
|
105
|
+
|
106
|
+
def _setup_menu_bar(self):
|
107
|
+
"""
|
108
|
+
Setup the menu bar for the main window.
|
109
|
+
"""
|
110
|
+
menu_bar = self.menuBar()
|
111
|
+
|
112
|
+
##########################################
|
113
|
+
# Launch menu
|
114
|
+
launch_menu = menu_bar.addMenu("New")
|
115
|
+
|
116
|
+
open_launcher_action = QAction("Open Launcher", self)
|
117
|
+
launch_menu.addAction(open_launcher_action)
|
118
|
+
open_launcher_action.triggered.connect(self._show_launcher)
|
119
|
+
|
120
|
+
########################################
|
121
|
+
# Theme menu
|
122
|
+
theme_menu = menu_bar.addMenu("Theme")
|
123
|
+
|
124
|
+
theme_group = QActionGroup(self)
|
125
|
+
light_theme_action = QAction("Light Theme", self, checkable=True)
|
126
|
+
dark_theme_action = QAction("Dark Theme", self, checkable=True)
|
127
|
+
theme_group.addAction(light_theme_action)
|
128
|
+
theme_group.addAction(dark_theme_action)
|
129
|
+
theme_group.setExclusive(True)
|
130
|
+
|
131
|
+
theme_menu.addAction(light_theme_action)
|
132
|
+
theme_menu.addAction(dark_theme_action)
|
133
|
+
|
134
|
+
# Connect theme actions
|
135
|
+
light_theme_action.triggered.connect(lambda: self.change_theme("light"))
|
136
|
+
dark_theme_action.triggered.connect(lambda: self.change_theme("dark"))
|
137
|
+
|
138
|
+
# Set the default theme
|
139
|
+
theme = self.app.theme.theme
|
140
|
+
if theme == "light":
|
141
|
+
light_theme_action.setChecked(True)
|
142
|
+
elif theme == "dark":
|
143
|
+
dark_theme_action.setChecked(True)
|
144
|
+
|
145
|
+
########################################
|
146
|
+
# Help menu
|
147
|
+
help_menu = menu_bar.addMenu("Help")
|
148
|
+
|
149
|
+
help_icon = QApplication.style().standardIcon(QStyle.SP_MessageBoxQuestion)
|
150
|
+
bug_icon = QApplication.style().standardIcon(QStyle.SP_MessageBoxInformation)
|
151
|
+
|
152
|
+
bec_docs = QAction("BEC Docs", self)
|
153
|
+
bec_docs.setIcon(help_icon)
|
154
|
+
widgets_docs = QAction("BEC Widgets Docs", self)
|
155
|
+
widgets_docs.setIcon(help_icon)
|
156
|
+
bug_report = QAction("Bug Report", self)
|
157
|
+
bug_report.setIcon(bug_icon)
|
158
|
+
|
159
|
+
bec_docs.triggered.connect(BECWebLinksMixin.open_bec_docs)
|
160
|
+
widgets_docs.triggered.connect(BECWebLinksMixin.open_bec_widgets_docs)
|
161
|
+
bug_report.triggered.connect(BECWebLinksMixin.open_bec_bug_report)
|
162
|
+
|
163
|
+
help_menu.addAction(bec_docs)
|
164
|
+
help_menu.addAction(widgets_docs)
|
165
|
+
help_menu.addAction(bug_report)
|
166
|
+
|
167
|
+
@SafeSlot(str)
|
168
|
+
def change_theme(self, theme: str):
|
169
|
+
apply_theme(theme)
|
170
|
+
|
171
|
+
def cleanup(self):
|
172
|
+
central_widget = self.centralWidget()
|
173
|
+
central_widget.close()
|
174
|
+
central_widget.deleteLater()
|
175
|
+
if not isinstance(central_widget, BECWidget):
|
176
|
+
# if the central widget is not a BECWidget, we need to call the cleanup method
|
177
|
+
# of all widgets whose parent is the current BECMainWindow
|
178
|
+
children = self.findChildren(BECWidget)
|
179
|
+
for child in children:
|
180
|
+
ancestor = WidgetHierarchy._get_becwidget_ancestor(child)
|
181
|
+
if ancestor is self:
|
182
|
+
child.cleanup()
|
183
|
+
child.close()
|
184
|
+
child.deleteLater()
|
185
|
+
super().cleanup()
|
186
|
+
|
187
|
+
|
188
|
+
class UILaunchWindow(BECMainWindow):
|
189
|
+
RPC = True
|
@@ -2,8 +2,8 @@ from bec_qthemes import material_icon
|
|
2
2
|
from qtpy.QtCore import Qt
|
3
3
|
from qtpy.QtWidgets import QHBoxLayout, QPushButton, QToolButton, QWidget
|
4
4
|
|
5
|
-
from bec_widgets.qt_utils.error_popups import SafeSlot
|
6
5
|
from bec_widgets.utils.bec_widget import BECWidget
|
6
|
+
from bec_widgets.utils.error_popups import SafeSlot
|
7
7
|
|
8
8
|
|
9
9
|
class AbortButton(BECWidget, QWidget):
|
@@ -11,6 +11,7 @@ class AbortButton(BECWidget, QWidget):
|
|
11
11
|
|
12
12
|
PLUGIN = True
|
13
13
|
ICON_NAME = "cancel"
|
14
|
+
RPC = True
|
14
15
|
|
15
16
|
def __init__(
|
16
17
|
self,
|
@@ -22,9 +23,7 @@ class AbortButton(BECWidget, QWidget):
|
|
22
23
|
scan_id=None,
|
23
24
|
**kwargs,
|
24
25
|
):
|
25
|
-
super().__init__(
|
26
|
-
QWidget.__init__(self, parent=parent)
|
27
|
-
|
26
|
+
super().__init__(parent=parent, client=client, gui_id=gui_id, config=config, **kwargs)
|
28
27
|
self.get_bec_shortcuts()
|
29
28
|
|
30
29
|
self.layout = QHBoxLayout(self)
|
@@ -2,8 +2,8 @@ from bec_qthemes import material_icon
|
|
2
2
|
from qtpy.QtCore import Qt
|
3
3
|
from qtpy.QtWidgets import QHBoxLayout, QMessageBox, QPushButton, QToolButton, QWidget
|
4
4
|
|
5
|
-
from bec_widgets.qt_utils.error_popups import SafeSlot
|
6
5
|
from bec_widgets.utils.bec_widget import BECWidget
|
6
|
+
from bec_widgets.utils.error_popups import SafeSlot
|
7
7
|
|
8
8
|
|
9
9
|
class ResetButton(BECWidget, QWidget):
|
@@ -11,11 +11,10 @@ class ResetButton(BECWidget, QWidget):
|
|
11
11
|
|
12
12
|
PLUGIN = True
|
13
13
|
ICON_NAME = "restart_alt"
|
14
|
+
RPC = True
|
14
15
|
|
15
16
|
def __init__(self, parent=None, client=None, config=None, gui_id=None, toolbar=False, **kwargs):
|
16
|
-
super().__init__(
|
17
|
-
QWidget.__init__(self, parent=parent)
|
18
|
-
|
17
|
+
super().__init__(parent=parent, client=client, gui_id=gui_id, config=config, **kwargs)
|
19
18
|
self.get_bec_shortcuts()
|
20
19
|
|
21
20
|
self.layout = QHBoxLayout(self)
|
@@ -2,8 +2,8 @@ from bec_qthemes import material_icon
|
|
2
2
|
from qtpy.QtCore import Qt
|
3
3
|
from qtpy.QtWidgets import QHBoxLayout, QPushButton, QToolButton, QWidget
|
4
4
|
|
5
|
-
from bec_widgets.qt_utils.error_popups import SafeSlot
|
6
5
|
from bec_widgets.utils.bec_widget import BECWidget
|
6
|
+
from bec_widgets.utils.error_popups import SafeSlot
|
7
7
|
|
8
8
|
|
9
9
|
class ResumeButton(BECWidget, QWidget):
|
@@ -11,10 +11,10 @@ class ResumeButton(BECWidget, QWidget):
|
|
11
11
|
|
12
12
|
PLUGIN = True
|
13
13
|
ICON_NAME = "resume"
|
14
|
+
RPC = True
|
14
15
|
|
15
16
|
def __init__(self, parent=None, client=None, config=None, gui_id=None, toolbar=False, **kwargs):
|
16
|
-
super().__init__(
|
17
|
-
QWidget.__init__(self, parent=parent)
|
17
|
+
super().__init__(parent=parent, client=client, gui_id=gui_id, config=config, **kwargs)
|
18
18
|
|
19
19
|
self.get_bec_shortcuts()
|
20
20
|
|
@@ -2,8 +2,8 @@ from bec_qthemes import material_icon
|
|
2
2
|
from qtpy.QtCore import Qt
|
3
3
|
from qtpy.QtWidgets import QHBoxLayout, QPushButton, QSizePolicy, QToolButton, QWidget
|
4
4
|
|
5
|
-
from bec_widgets.qt_utils.error_popups import SafeSlot
|
6
5
|
from bec_widgets.utils.bec_widget import BECWidget
|
6
|
+
from bec_widgets.utils.error_popups import SafeSlot
|
7
7
|
|
8
8
|
|
9
9
|
class StopButton(BECWidget, QWidget):
|
@@ -11,10 +11,10 @@ class StopButton(BECWidget, QWidget):
|
|
11
11
|
|
12
12
|
PLUGIN = True
|
13
13
|
ICON_NAME = "dangerous"
|
14
|
+
RPC = True
|
14
15
|
|
15
16
|
def __init__(self, parent=None, client=None, config=None, gui_id=None, toolbar=False, **kwargs):
|
16
|
-
super().__init__(
|
17
|
-
QWidget.__init__(self, parent=parent)
|
17
|
+
super().__init__(parent=parent, client=client, gui_id=gui_id, config=config, **kwargs)
|
18
18
|
|
19
19
|
self.get_bec_shortcuts()
|
20
20
|
|
@@ -54,9 +54,20 @@ class StopButton(BECWidget, QWidget):
|
|
54
54
|
if __name__ == "__main__": # pragma: no cover
|
55
55
|
import sys
|
56
56
|
|
57
|
-
from qtpy.QtWidgets import QApplication
|
57
|
+
from qtpy.QtWidgets import QApplication, QVBoxLayout, QWidget
|
58
58
|
|
59
|
-
|
60
|
-
|
61
|
-
|
59
|
+
from bec_widgets.widgets.control.buttons.stop_button.stop_button import StopButton
|
60
|
+
|
61
|
+
class MyGui(QWidget):
|
62
|
+
def __init__(self):
|
63
|
+
super().__init__()
|
64
|
+
self.setLayout(QVBoxLayout())
|
65
|
+
# Create and add the StopButton to the layout
|
66
|
+
self.stop_button = StopButton()
|
67
|
+
self.layout().addWidget(self.stop_button)
|
68
|
+
|
69
|
+
# Example of how this custom GUI might be used:
|
70
|
+
app = QApplication([])
|
71
|
+
my_gui = MyGui()
|
72
|
+
my_gui.show()
|
62
73
|
sys.exit(app.exec_())
|
@@ -8,13 +8,26 @@ from bec_widgets.utils.colors import get_accent_colors, get_theme_palette
|
|
8
8
|
|
9
9
|
|
10
10
|
class PositionIndicator(BECWidget, QWidget):
|
11
|
-
|
11
|
+
"""
|
12
|
+
Display a position within a defined range, e.g. motor limits.
|
13
|
+
"""
|
14
|
+
|
15
|
+
USER_ACCESS = [
|
16
|
+
"set_value",
|
17
|
+
"set_range",
|
18
|
+
"vertical",
|
19
|
+
"vertical.setter",
|
20
|
+
"indicator_width",
|
21
|
+
"indicator_width.setter",
|
22
|
+
"rounded_corners",
|
23
|
+
"rounded_corners.setter",
|
24
|
+
]
|
12
25
|
PLUGIN = True
|
13
26
|
ICON_NAME = "horizontal_distribute"
|
14
27
|
|
15
28
|
def __init__(self, parent=None, client=None, config=None, gui_id=None, **kwargs):
|
16
|
-
super().__init__(
|
17
|
-
|
29
|
+
super().__init__(parent=parent, client=client, gui_id=gui_id, config=config, **kwargs)
|
30
|
+
|
18
31
|
self.position = 50
|
19
32
|
self.min_value = 0
|
20
33
|
self.max_value = 100
|
@@ -205,6 +218,12 @@ class PositionIndicator(BECWidget, QWidget):
|
|
205
218
|
@Slot(int)
|
206
219
|
@Slot(float)
|
207
220
|
def set_value(self, position: float):
|
221
|
+
"""
|
222
|
+
Set the position of the indicator
|
223
|
+
|
224
|
+
Args:
|
225
|
+
position: The new position of the indicator
|
226
|
+
"""
|
208
227
|
self.position = position
|
209
228
|
self.update()
|
210
229
|
|
@@ -16,8 +16,8 @@ from qtpy.QtWidgets import (
|
|
16
16
|
QVBoxLayout,
|
17
17
|
)
|
18
18
|
|
19
|
-
from bec_widgets.qt_utils.compact_popup import CompactPopupWidget
|
20
19
|
from bec_widgets.utils.bec_widget import BECWidget
|
20
|
+
from bec_widgets.utils.compact_popup import CompactPopupWidget
|
21
21
|
from bec_widgets.widgets.control.device_control.position_indicator.position_indicator import (
|
22
22
|
PositionIndicator,
|
23
23
|
)
|
@@ -40,6 +40,7 @@ class DeviceUpdateUIComponents(TypedDict):
|
|
40
40
|
stop: QPushButton
|
41
41
|
tweak_increase: QPushButton
|
42
42
|
tweak_decrease: QPushButton
|
43
|
+
units: QLabel
|
43
44
|
|
44
45
|
|
45
46
|
class PositionerBoxBase(BECWidget, CompactPopupWidget):
|
@@ -47,6 +48,7 @@ class PositionerBoxBase(BECWidget, CompactPopupWidget):
|
|
47
48
|
|
48
49
|
current_path = ""
|
49
50
|
ICON_NAME = "switch_right"
|
51
|
+
RPC = False
|
50
52
|
|
51
53
|
def __init__(self, parent=None, **kwargs):
|
52
54
|
"""Initialize the PositionerBox widget.
|
@@ -55,8 +57,7 @@ class PositionerBoxBase(BECWidget, CompactPopupWidget):
|
|
55
57
|
parent: The parent widget.
|
56
58
|
device (Positioner): The device to control.
|
57
59
|
"""
|
58
|
-
super().__init__(**kwargs)
|
59
|
-
CompactPopupWidget.__init__(self, parent=parent, layout=QVBoxLayout)
|
60
|
+
super().__init__(parent=parent, layout=QVBoxLayout, **kwargs)
|
60
61
|
self._dialog = None
|
61
62
|
self.get_bec_shortcuts()
|
62
63
|
|
@@ -84,16 +85,33 @@ class PositionerBoxBase(BECWidget, CompactPopupWidget):
|
|
84
85
|
limit_update: Callable[[tuple[float, float]], None],
|
85
86
|
):
|
86
87
|
"""Init the device view and readback"""
|
87
|
-
if self._check_device_is_valid(device):
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
88
|
+
if not self._check_device_is_valid(device):
|
89
|
+
return
|
90
|
+
|
91
|
+
data = self.dev[device].read()
|
92
|
+
self._on_device_readback(
|
93
|
+
device,
|
94
|
+
self._device_ui_components(device),
|
95
|
+
{"signals": data},
|
96
|
+
{},
|
97
|
+
position_emit,
|
98
|
+
limit_update,
|
99
|
+
)
|
100
|
+
|
101
|
+
ui = self._device_ui_components(device)
|
102
|
+
if not ui.get("units"):
|
103
|
+
return
|
104
|
+
|
105
|
+
try:
|
106
|
+
egu = f"[{self.dev[device].egu()}]"
|
107
|
+
except Exception:
|
108
|
+
egu = ""
|
109
|
+
|
110
|
+
if egu:
|
111
|
+
ui["units"].setVisible(True)
|
112
|
+
ui["units"].setText(egu)
|
113
|
+
else:
|
114
|
+
ui["units"].setVisible(False)
|
97
115
|
|
98
116
|
def _stop_device(self, device: str):
|
99
117
|
"""Stop call"""
|
@@ -11,9 +11,9 @@ from qtpy.QtCore import Signal
|
|
11
11
|
from qtpy.QtGui import QDoubleValidator
|
12
12
|
from qtpy.QtWidgets import QDoubleSpinBox
|
13
13
|
|
14
|
-
from bec_widgets.qt_utils.error_popups import SafeProperty, SafeSlot
|
15
14
|
from bec_widgets.utils import UILoader
|
16
15
|
from bec_widgets.utils.colors import get_accent_colors, set_theme
|
16
|
+
from bec_widgets.utils.error_popups import SafeProperty, SafeSlot
|
17
17
|
from bec_widgets.widgets.control.device_control.positioner_box._base import PositionerBoxBase
|
18
18
|
from bec_widgets.widgets.control.device_control.positioner_box._base.positioner_box_base import (
|
19
19
|
DeviceUpdateUIComponents,
|
@@ -31,6 +31,7 @@ class PositionerBox(PositionerBoxBase):
|
|
31
31
|
dimensions = (234, 224)
|
32
32
|
|
33
33
|
PLUGIN = True
|
34
|
+
RPC = True
|
34
35
|
|
35
36
|
USER_ACCESS = ["set_positioner"]
|
36
37
|
device_changed = Signal(str, str)
|
@@ -170,6 +171,7 @@ class PositionerBox(PositionerBoxBase):
|
|
170
171
|
"stop": self.ui.stop,
|
171
172
|
"tweak_increase": self.ui.tweak_right,
|
172
173
|
"tweak_decrease": self.ui.tweak_left,
|
174
|
+
"units": self.ui.units,
|
173
175
|
}
|
174
176
|
|
175
177
|
@SafeSlot(dict, dict)
|
@@ -135,6 +135,29 @@
|
|
135
135
|
</property>
|
136
136
|
</widget>
|
137
137
|
</item>
|
138
|
+
<item>
|
139
|
+
<spacer name="horizontalSpacer_2">
|
140
|
+
<property name="orientation">
|
141
|
+
<enum>Qt::Orientation::Horizontal</enum>
|
142
|
+
</property>
|
143
|
+
<property name="sizeHint" stdset="0">
|
144
|
+
<size>
|
145
|
+
<width>40</width>
|
146
|
+
<height>20</height>
|
147
|
+
</size>
|
148
|
+
</property>
|
149
|
+
</spacer>
|
150
|
+
</item>
|
151
|
+
<item>
|
152
|
+
<widget class="QLabel" name="units">
|
153
|
+
<property name="toolTip">
|
154
|
+
<string>Motor units</string>
|
155
|
+
</property>
|
156
|
+
<property name="text">
|
157
|
+
<string></string>
|
158
|
+
</property>
|
159
|
+
</widget>
|
160
|
+
</item>
|
138
161
|
<item>
|
139
162
|
<spacer name="horizontalSpacer">
|
140
163
|
<property name="orientation">
|
@@ -204,14 +227,14 @@
|
|
204
227
|
</widget>
|
205
228
|
<customwidgets>
|
206
229
|
<customwidget>
|
207
|
-
<class>
|
230
|
+
<class>PositionIndicator</class>
|
208
231
|
<extends>QWidget</extends>
|
209
|
-
<header>
|
232
|
+
<header>position_indicator</header>
|
210
233
|
</customwidget>
|
211
234
|
<customwidget>
|
212
|
-
<class>
|
235
|
+
<class>SpinnerWidget</class>
|
213
236
|
<extends>QWidget</extends>
|
214
|
-
<header>
|
237
|
+
<header>spinner_widget</header>
|
215
238
|
</customwidget>
|
216
239
|
</customwidgets>
|
217
240
|
<resources/>
|
bec_widgets/widgets/control/device_control/positioner_box/positioner_box_2d/positioner_box_2d.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
"""
|
1
|
+
"""Module for a PositionerBox2D widget to control two positioner devices."""
|
2
2
|
|
3
3
|
from __future__ import annotations
|
4
4
|
|
@@ -12,9 +12,9 @@ from qtpy.QtCore import Signal
|
|
12
12
|
from qtpy.QtGui import QDoubleValidator
|
13
13
|
from qtpy.QtWidgets import QDoubleSpinBox
|
14
14
|
|
15
|
-
from bec_widgets.qt_utils.error_popups import SafeProperty, SafeSlot
|
16
15
|
from bec_widgets.utils import UILoader
|
17
16
|
from bec_widgets.utils.colors import set_theme
|
17
|
+
from bec_widgets.utils.error_popups import SafeProperty, SafeSlot
|
18
18
|
from bec_widgets.widgets.control.device_control.positioner_box._base import PositionerBoxBase
|
19
19
|
from bec_widgets.widgets.control.device_control.positioner_box._base.positioner_box_base import (
|
20
20
|
DeviceUpdateUIComponents,
|
@@ -33,6 +33,7 @@ class PositionerBox2D(PositionerBoxBase):
|
|
33
33
|
ui_file = "positioner_box_2d.ui"
|
34
34
|
|
35
35
|
PLUGIN = True
|
36
|
+
RPC = True
|
36
37
|
USER_ACCESS = ["set_positioner_hor", "set_positioner_ver"]
|
37
38
|
|
38
39
|
device_changed_hor = Signal(str, str)
|
@@ -312,6 +313,7 @@ class PositionerBox2D(PositionerBoxBase):
|
|
312
313
|
"stop": self.ui.stop_button,
|
313
314
|
"tweak_increase": self.ui.tweak_increase_hor,
|
314
315
|
"tweak_decrease": self.ui.tweak_decrease_hor,
|
316
|
+
"units": self.ui.units_hor,
|
315
317
|
}
|
316
318
|
elif device == "vertical":
|
317
319
|
return {
|
@@ -324,6 +326,7 @@ class PositionerBox2D(PositionerBoxBase):
|
|
324
326
|
"stop": self.ui.stop_button,
|
325
327
|
"tweak_increase": self.ui.tweak_increase_ver,
|
326
328
|
"tweak_decrease": self.ui.tweak_decrease_ver,
|
329
|
+
"units": self.ui.units_ver,
|
327
330
|
}
|
328
331
|
else:
|
329
332
|
raise ValueError(f"Device {device} is not represented by this UI")
|