bec-widgets 0.52.0__py3-none-any.whl → 0.53.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.
- .git_hooks/pre-commit +3 -0
- .gitignore +177 -0
- .gitlab/issue_templates/bug_report_template.md +17 -0
- .gitlab/issue_templates/documentation_update_template.md +27 -0
- .gitlab/issue_templates/feature_request_template.md +40 -0
- .gitlab/merge_request_templates/default.md +28 -0
- .gitlab-ci.yml +225 -0
- .pylintrc +581 -0
- .readthedocs.yaml +25 -0
- CHANGELOG.md +176 -0
- PKG-INFO +33 -0
- bec_widgets-0.52.0.dist-info/METADATA → README.md +6 -42
- bec_widgets/cli/client.py +132 -17
- bec_widgets/cli/client_utils.py +1 -0
- bec_widgets/cli/generate_cli.py +1 -0
- bec_widgets/cli/rpc_register.py +4 -0
- bec_widgets/cli/rpc_wigdet_handler.py +2 -3
- bec_widgets/examples/modular_app/modular.ui +92 -0
- bec_widgets/examples/modular_app/modular_app.py +197 -0
- bec_widgets/examples/motor_movement/motor_control_compilations.py +1 -1
- bec_widgets/examples/motor_movement/motor_example.py +3 -12
- bec_widgets/utils/bec_connector.py +7 -0
- bec_widgets/utils/bec_dispatcher.py +1 -3
- bec_widgets/utils/bec_table.py +1 -0
- bec_widgets/utils/container_utils.py +3 -0
- bec_widgets/utils/crosshair.py +1 -0
- bec_widgets/utils/entry_validator.py +2 -0
- bec_widgets/utils/layout_manager.py +4 -0
- bec_widgets/utils/widget_io.py +5 -0
- bec_widgets/utils/yaml_dialog.py +2 -0
- bec_widgets/validation/monitor_config_validator.py +2 -1
- bec_widgets/widgets/dock/dock_area.py +6 -4
- bec_widgets/widgets/figure/figure.py +15 -15
- bec_widgets/widgets/monitor/config_dialog.py +3 -19
- bec_widgets/widgets/monitor/example_configs/config_device.yaml +60 -0
- bec_widgets/widgets/monitor/example_configs/config_scans.yaml +92 -0
- bec_widgets/widgets/motor_map/motor_map.py +3 -14
- bec_widgets/widgets/plots/image.py +41 -0
- bec_widgets/widgets/plots/motor_map.py +16 -9
- bec_widgets/widgets/plots/plot_base.py +10 -0
- bec_widgets/widgets/plots/waveform.py +31 -0
- bec_widgets/widgets/scan_control/scan_control.py +11 -5
- bec_widgets/widgets/toolbar/toolbar.py +1 -0
- bec_widgets-0.53.0.dist-info/METADATA +33 -0
- bec_widgets-0.53.0.dist-info/RECORD +156 -0
- {bec_widgets-0.52.0.dist-info → bec_widgets-0.53.0.dist-info}/WHEEL +1 -2
- bec_widgets-0.53.0.dist-info/licenses/LICENSE +29 -0
- docs/Makefile +20 -0
- docs/_templates/custom-class-template.rst +34 -0
- docs/_templates/custom-module-template.rst +66 -0
- docs/conf.py +81 -0
- docs/developer/developer.md +26 -0
- docs/developer/reference.md +10 -0
- docs/index.md +39 -0
- docs/introduction/introduction.md +18 -0
- docs/make.bat +35 -0
- docs/requirements.txt +10 -0
- docs/user/apps/modular_app.md +6 -0
- docs/user/apps/motor_app.md +34 -0
- docs/user/apps/motor_app_10fps.gif +0 -0
- docs/user/apps/plot_app.md +6 -0
- docs/user/apps.md +39 -0
- docs/user/customisation.md +13 -0
- docs/user/installation.md +46 -0
- docs/user/user.md +38 -0
- docs/user/widgets/motor.gif +0 -0
- docs/user/widgets/scatter_2D.gif +0 -0
- docs/user/widgets/w1D.gif +0 -0
- docs/user/widgets.md +41 -0
- pyproject.toml +94 -0
- tests/unit_tests/test_bec_dispatcher.py +3 -26
- tests/unit_tests/test_bec_figure.py +1 -5
- tests/unit_tests/test_bec_motor_map.py +1 -4
- tests/unit_tests/test_config_dialog.py +1 -5
- tests/unit_tests/test_configs/config_device.yaml +33 -0
- tests/unit_tests/test_configs/config_device_no_entry.yaml +27 -0
- tests/unit_tests/test_configs/config_scan.yaml +82 -0
- tests/unit_tests/test_motor_control.py +1 -1
- tests/unit_tests/test_motor_map.py +5 -20
- tests/unit_tests/test_stream_plot.py +2 -12
- bec_widgets/utils/ctrl_c.py +0 -39
- bec_widgets-0.52.0.dist-info/RECORD +0 -115
- bec_widgets-0.52.0.dist-info/top_level.txt +0 -2
- /bec_widgets-0.52.0.dist-info/LICENSE → /LICENSE +0 -0
- /bec_widgets/{simulations/__init__.py → examples/modular_app/___init__.py} +0 -0
bec_widgets/cli/client_utils.py
CHANGED
bec_widgets/cli/generate_cli.py
CHANGED
bec_widgets/cli/rpc_register.py
CHANGED
@@ -28,6 +28,7 @@ class RPCRegister:
|
|
28
28
|
def add_rpc(self, rpc: QObject):
|
29
29
|
"""
|
30
30
|
Add an RPC object to the register.
|
31
|
+
|
31
32
|
Args:
|
32
33
|
rpc(QObject): The RPC object to be added to the register.
|
33
34
|
"""
|
@@ -38,6 +39,7 @@ class RPCRegister:
|
|
38
39
|
def remove_rpc(self, rpc: str):
|
39
40
|
"""
|
40
41
|
Remove an RPC object from the register.
|
42
|
+
|
41
43
|
Args:
|
42
44
|
rpc(str): The RPC object to be removed from the register.
|
43
45
|
"""
|
@@ -48,6 +50,7 @@ class RPCRegister:
|
|
48
50
|
def get_rpc_by_id(self, gui_id: str) -> QObject:
|
49
51
|
"""
|
50
52
|
Get an RPC object by its ID.
|
53
|
+
|
51
54
|
Args:
|
52
55
|
gui_id(str): The ID of the RPC object to be retrieved.
|
53
56
|
|
@@ -60,6 +63,7 @@ class RPCRegister:
|
|
60
63
|
def list_all_connections(self) -> dict:
|
61
64
|
"""
|
62
65
|
List all the registered RPC objects.
|
66
|
+
|
63
67
|
Returns:
|
64
68
|
dict: A dictionary containing all the registered RPC objects.
|
65
69
|
"""
|
@@ -5,14 +5,13 @@ from bec_widgets.widgets.figure import BECFigure
|
|
5
5
|
class RPCWidgetHandler:
|
6
6
|
"""Handler class for creating widgets from RPC messages."""
|
7
7
|
|
8
|
-
widget_classes = {
|
9
|
-
"BECFigure": BECFigure,
|
10
|
-
}
|
8
|
+
widget_classes = {"BECFigure": BECFigure}
|
11
9
|
|
12
10
|
@staticmethod
|
13
11
|
def create_widget(widget_type, **kwargs) -> BECConnector:
|
14
12
|
"""
|
15
13
|
Create a widget from an RPC message.
|
14
|
+
|
16
15
|
Args:
|
17
16
|
widget_type(str): The type of the widget.
|
18
17
|
**kwargs: The keyword arguments for the widget.
|
@@ -0,0 +1,92 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<ui version="4.0">
|
3
|
+
<class>MainWindow</class>
|
4
|
+
<widget class="QMainWindow" name="MainWindow">
|
5
|
+
<property name="geometry">
|
6
|
+
<rect>
|
7
|
+
<x>0</x>
|
8
|
+
<y>0</y>
|
9
|
+
<width>1433</width>
|
10
|
+
<height>689</height>
|
11
|
+
</rect>
|
12
|
+
</property>
|
13
|
+
<property name="windowTitle">
|
14
|
+
<string>MainWindow</string>
|
15
|
+
</property>
|
16
|
+
<widget class="QWidget" name="centralwidget">
|
17
|
+
<layout class="QGridLayout" name="gridLayout">
|
18
|
+
<item row="1" column="2">
|
19
|
+
<widget class="QLabel" name="label_3">
|
20
|
+
<property name="text">
|
21
|
+
<string>Plot Config 2</string>
|
22
|
+
</property>
|
23
|
+
</widget>
|
24
|
+
</item>
|
25
|
+
<item row="3" column="0" colspan="2">
|
26
|
+
<widget class="BECMonitor" name="plot_1"/>
|
27
|
+
</item>
|
28
|
+
<item row="1" column="3">
|
29
|
+
<widget class="QPushButton" name="pushButton_setting_2">
|
30
|
+
<property name="text">
|
31
|
+
<string>Setting Plot 2</string>
|
32
|
+
</property>
|
33
|
+
</widget>
|
34
|
+
</item>
|
35
|
+
<item row="3" column="2" colspan="2">
|
36
|
+
<widget class="BECMonitor" name="plot_2"/>
|
37
|
+
</item>
|
38
|
+
<item row="1" column="4">
|
39
|
+
<widget class="QLabel" name="label_2">
|
40
|
+
<property name="text">
|
41
|
+
<string>Plot Scan Types = True</string>
|
42
|
+
</property>
|
43
|
+
</widget>
|
44
|
+
</item>
|
45
|
+
<item row="1" column="1">
|
46
|
+
<widget class="QPushButton" name="pushButton_setting_1">
|
47
|
+
<property name="text">
|
48
|
+
<string>Setting Plot 1</string>
|
49
|
+
</property>
|
50
|
+
</widget>
|
51
|
+
</item>
|
52
|
+
<item row="1" column="0">
|
53
|
+
<widget class="QLabel" name="label">
|
54
|
+
<property name="text">
|
55
|
+
<string>Plot Config 1</string>
|
56
|
+
</property>
|
57
|
+
</widget>
|
58
|
+
</item>
|
59
|
+
<item row="1" column="5">
|
60
|
+
<widget class="QPushButton" name="pushButton_setting_3">
|
61
|
+
<property name="text">
|
62
|
+
<string>Setting Plot 3</string>
|
63
|
+
</property>
|
64
|
+
</widget>
|
65
|
+
</item>
|
66
|
+
<item row="3" column="4" colspan="2">
|
67
|
+
<widget class="BECMonitor" name="plot_3"/>
|
68
|
+
</item>
|
69
|
+
</layout>
|
70
|
+
</widget>
|
71
|
+
<widget class="QMenuBar" name="menubar">
|
72
|
+
<property name="geometry">
|
73
|
+
<rect>
|
74
|
+
<x>0</x>
|
75
|
+
<y>0</y>
|
76
|
+
<width>1433</width>
|
77
|
+
<height>37</height>
|
78
|
+
</rect>
|
79
|
+
</property>
|
80
|
+
</widget>
|
81
|
+
<widget class="QStatusBar" name="statusbar"/>
|
82
|
+
</widget>
|
83
|
+
<customwidgets>
|
84
|
+
<customwidget>
|
85
|
+
<class>BECMonitor</class>
|
86
|
+
<extends>QGraphicsView</extends>
|
87
|
+
<header location="global">bec_widgets.widgets.h</header>
|
88
|
+
</customwidget>
|
89
|
+
</customwidgets>
|
90
|
+
<resources/>
|
91
|
+
<connections/>
|
92
|
+
</ui>
|
@@ -0,0 +1,197 @@
|
|
1
|
+
import os
|
2
|
+
|
3
|
+
from qtpy import uic
|
4
|
+
from qtpy.QtWidgets import QApplication, QMainWindow
|
5
|
+
|
6
|
+
from bec_widgets.utils.bec_dispatcher import BECDispatcher
|
7
|
+
from bec_widgets.widgets import BECMonitor
|
8
|
+
|
9
|
+
# some default configs for demonstration purposes
|
10
|
+
CONFIG_SIMPLE = {
|
11
|
+
"plot_settings": {
|
12
|
+
"background_color": "black",
|
13
|
+
"num_columns": 2,
|
14
|
+
"colormap": "plasma",
|
15
|
+
"scan_types": False,
|
16
|
+
},
|
17
|
+
"plot_data": [
|
18
|
+
{
|
19
|
+
"plot_name": "BPM4i plots vs samx",
|
20
|
+
"x_label": "Motor X",
|
21
|
+
"y_label": "bpm4i",
|
22
|
+
"sources": [
|
23
|
+
{
|
24
|
+
"type": "scan_segment",
|
25
|
+
"signals": {
|
26
|
+
"x": [{"name": "samx"}],
|
27
|
+
"y": [{"name": "bpm4i", "entry": "bpm4i"}],
|
28
|
+
},
|
29
|
+
},
|
30
|
+
# {
|
31
|
+
# "type": "history",
|
32
|
+
# "signals": {
|
33
|
+
# "x": [{"name": "samx"}],
|
34
|
+
# "y": [{"name": "bpm4i", "entry": "bpm4i"}],
|
35
|
+
# },
|
36
|
+
# },
|
37
|
+
# {
|
38
|
+
# "type": "dap",
|
39
|
+
# 'worker':'some_worker',
|
40
|
+
# "signals": {
|
41
|
+
# "x": [{"name": "samx"}],
|
42
|
+
# "y": [{"name": "bpm4i", "entry": "bpm4i"}],
|
43
|
+
# },
|
44
|
+
# },
|
45
|
+
],
|
46
|
+
},
|
47
|
+
{
|
48
|
+
"plot_name": "Gauss plots vs samx",
|
49
|
+
"x_label": "Motor X",
|
50
|
+
"y_label": "Gauss",
|
51
|
+
"sources": [
|
52
|
+
{
|
53
|
+
"type": "scan_segment",
|
54
|
+
"signals": {
|
55
|
+
"x": [{"name": "samx", "entry": "samx"}],
|
56
|
+
"y": [{"name": "gauss_bpm"}, {"name": "gauss_adc1"}],
|
57
|
+
},
|
58
|
+
}
|
59
|
+
],
|
60
|
+
},
|
61
|
+
],
|
62
|
+
}
|
63
|
+
|
64
|
+
|
65
|
+
CONFIG_SCAN_MODE = {
|
66
|
+
"plot_settings": {
|
67
|
+
"background_color": "white",
|
68
|
+
"num_columns": 3,
|
69
|
+
"colormap": "plasma",
|
70
|
+
"scan_types": True,
|
71
|
+
},
|
72
|
+
"plot_data": {
|
73
|
+
"grid_scan": [
|
74
|
+
{
|
75
|
+
"plot_name": "Grid plot 1",
|
76
|
+
"x_label": "Motor X",
|
77
|
+
"y_label": "BPM",
|
78
|
+
"sources": [
|
79
|
+
{
|
80
|
+
"type": "scan_segment",
|
81
|
+
"signals": {
|
82
|
+
"x": [{"name": "samx", "entry": "samx"}],
|
83
|
+
"y": [{"name": "gauss_bpm"}],
|
84
|
+
},
|
85
|
+
}
|
86
|
+
],
|
87
|
+
},
|
88
|
+
{
|
89
|
+
"plot_name": "Grid plot 2",
|
90
|
+
"x_label": "Motor X",
|
91
|
+
"y_label": "BPM",
|
92
|
+
"sources": [
|
93
|
+
{
|
94
|
+
"type": "scan_segment",
|
95
|
+
"signals": {
|
96
|
+
"x": [{"name": "samx", "entry": "samx"}],
|
97
|
+
"y": [{"name": "gauss_adc1"}],
|
98
|
+
},
|
99
|
+
}
|
100
|
+
],
|
101
|
+
},
|
102
|
+
{
|
103
|
+
"plot_name": "Grid plot 3",
|
104
|
+
"x_label": "Motor X",
|
105
|
+
"y_label": "BPM",
|
106
|
+
"sources": [
|
107
|
+
{
|
108
|
+
"type": "scan_segment",
|
109
|
+
"signals": {"x": [{"name": "samy"}], "y": [{"name": "gauss_adc2"}]},
|
110
|
+
}
|
111
|
+
],
|
112
|
+
},
|
113
|
+
{
|
114
|
+
"plot_name": "Grid plot 4",
|
115
|
+
"x_label": "Motor X",
|
116
|
+
"y_label": "BPM",
|
117
|
+
"sources": [
|
118
|
+
{
|
119
|
+
"type": "scan_segment",
|
120
|
+
"signals": {
|
121
|
+
"x": [{"name": "samy", "entry": "samy"}],
|
122
|
+
"y": [{"name": "gauss_adc3"}],
|
123
|
+
},
|
124
|
+
}
|
125
|
+
],
|
126
|
+
},
|
127
|
+
],
|
128
|
+
"line_scan": [
|
129
|
+
{
|
130
|
+
"plot_name": "BPM plots vs samx",
|
131
|
+
"x_label": "Motor X",
|
132
|
+
"y_label": "Gauss",
|
133
|
+
"sources": [
|
134
|
+
{
|
135
|
+
"type": "scan_segment",
|
136
|
+
"signals": {
|
137
|
+
"x": [{"name": "samx", "entry": "samx"}],
|
138
|
+
"y": [{"name": "bpm4i"}],
|
139
|
+
},
|
140
|
+
}
|
141
|
+
],
|
142
|
+
},
|
143
|
+
{
|
144
|
+
"plot_name": "Gauss plots vs samx",
|
145
|
+
"x_label": "Motor X",
|
146
|
+
"y_label": "Gauss",
|
147
|
+
"sources": [
|
148
|
+
{
|
149
|
+
"type": "scan_segment",
|
150
|
+
"signals": {
|
151
|
+
"x": [{"name": "samx", "entry": "samx"}],
|
152
|
+
"y": [{"name": "gauss_bpm"}, {"name": "gauss_adc1"}],
|
153
|
+
},
|
154
|
+
}
|
155
|
+
],
|
156
|
+
},
|
157
|
+
],
|
158
|
+
},
|
159
|
+
}
|
160
|
+
|
161
|
+
|
162
|
+
class ModularApp(QMainWindow):
|
163
|
+
def __init__(self, client=None, parent=None):
|
164
|
+
super(ModularApp, self).__init__(parent)
|
165
|
+
|
166
|
+
# Client and device manager from BEC
|
167
|
+
self.client = BECDispatcher().client if client is None else client
|
168
|
+
|
169
|
+
# Loading UI
|
170
|
+
current_path = os.path.dirname(__file__)
|
171
|
+
uic.loadUi(os.path.join(current_path, "modular.ui"), self)
|
172
|
+
|
173
|
+
self._init_plots()
|
174
|
+
|
175
|
+
def _init_plots(self):
|
176
|
+
"""Initialize plots and connect the buttons to the config dialogs"""
|
177
|
+
plots = [self.plot_1, self.plot_2, self.plot_3]
|
178
|
+
configs = [CONFIG_SIMPLE, CONFIG_SCAN_MODE, CONFIG_SCAN_MODE]
|
179
|
+
buttons = [self.pushButton_setting_1, self.pushButton_setting_2, self.pushButton_setting_3]
|
180
|
+
|
181
|
+
# hook plots, configs and buttons together
|
182
|
+
for plot, config, button in zip(plots, configs, buttons):
|
183
|
+
plot.on_config_update(config)
|
184
|
+
button.clicked.connect(plot.show_config_dialog)
|
185
|
+
|
186
|
+
|
187
|
+
if __name__ == "__main__":
|
188
|
+
# BECclient global variables
|
189
|
+
client = BECDispatcher().client
|
190
|
+
client.start()
|
191
|
+
|
192
|
+
app = QApplication([])
|
193
|
+
modularApp = ModularApp(client=client)
|
194
|
+
|
195
|
+
window = modularApp
|
196
|
+
window.show()
|
197
|
+
app.exec()
|
@@ -1068,10 +1068,7 @@ class MotorApp(QWidget):
|
|
1068
1068
|
|
1069
1069
|
# PyQtGraph Controls
|
1070
1070
|
layout.addWidget(QLabel("Graph Window Controls:"))
|
1071
|
-
graph_controls = [
|
1072
|
-
("Left Drag", "Pan the view"),
|
1073
|
-
("Right Drag or Scroll", "Zoom in/out"),
|
1074
|
-
]
|
1071
|
+
graph_controls = [("Left Drag", "Pan the view"), ("Right Drag or Scroll", "Zoom in/out")]
|
1075
1072
|
for action, description in graph_controls:
|
1076
1073
|
layout.addWidget(QLabel(f"{action} - {description}"))
|
1077
1074
|
|
@@ -1111,10 +1108,7 @@ class MotorControl(QThread):
|
|
1111
1108
|
motors_selected = pyqtSignal(object, object) # Signal to emit when the motors are selected
|
1112
1109
|
# progress_updated = pyqtSignal(int) #TODO Signal to emit progress percentage
|
1113
1110
|
|
1114
|
-
def __init__(
|
1115
|
-
self,
|
1116
|
-
parent=None,
|
1117
|
-
):
|
1111
|
+
def __init__(self, parent=None):
|
1118
1112
|
super().__init__(parent)
|
1119
1113
|
|
1120
1114
|
self.action = None
|
@@ -1131,10 +1125,7 @@ class MotorControl(QThread):
|
|
1131
1125
|
self.motor_x_name = motor_x_name
|
1132
1126
|
self.motor_y_name = motor_y_name
|
1133
1127
|
|
1134
|
-
self.motor_x, self.motor_y = (
|
1135
|
-
dev[self.motor_x_name],
|
1136
|
-
dev[self.motor_y_name],
|
1137
|
-
)
|
1128
|
+
self.motor_x, self.motor_y = (dev[self.motor_x_name], dev[self.motor_y_name])
|
1138
1129
|
|
1139
1130
|
(self.current_x, self.current_y) = self.get_coordinates()
|
1140
1131
|
|
@@ -78,6 +78,7 @@ class BECConnector:
|
|
78
78
|
def config_dict(self) -> dict:
|
79
79
|
"""
|
80
80
|
Get the configuration of the widget.
|
81
|
+
|
81
82
|
Returns:
|
82
83
|
dict: The configuration of the widget.
|
83
84
|
"""
|
@@ -87,6 +88,7 @@ class BECConnector:
|
|
87
88
|
def config_dict(self, config: BaseModel) -> None:
|
88
89
|
"""
|
89
90
|
Get the configuration of the widget.
|
91
|
+
|
90
92
|
Returns:
|
91
93
|
dict: The configuration of the widget.
|
92
94
|
"""
|
@@ -96,6 +98,7 @@ class BECConnector:
|
|
96
98
|
def set_gui_id(self, gui_id: str) -> None:
|
97
99
|
"""
|
98
100
|
Set the GUI ID for the widget.
|
101
|
+
|
99
102
|
Args:
|
100
103
|
gui_id(str): GUI ID
|
101
104
|
"""
|
@@ -116,6 +119,7 @@ class BECConnector:
|
|
116
119
|
|
117
120
|
def update_client(self, client) -> None:
|
118
121
|
"""Update the client and device manager from BEC and create object for BEC shortcuts.
|
122
|
+
|
119
123
|
Args:
|
120
124
|
client: BEC client
|
121
125
|
"""
|
@@ -126,6 +130,7 @@ class BECConnector:
|
|
126
130
|
def on_config_update(self, config: ConnectionConfig | dict) -> None:
|
127
131
|
"""
|
128
132
|
Update the configuration for the widget.
|
133
|
+
|
129
134
|
Args:
|
130
135
|
config(ConnectionConfig): Configuration settings.
|
131
136
|
"""
|
@@ -138,8 +143,10 @@ class BECConnector:
|
|
138
143
|
def get_config(self, dict_output: bool = True) -> dict | BaseModel:
|
139
144
|
"""
|
140
145
|
Get the configuration of the widget.
|
146
|
+
|
141
147
|
Args:
|
142
148
|
dict_output(bool): If True, return the configuration as a dictionary. If False, return the configuration as a pydantic model.
|
149
|
+
|
143
150
|
Returns:
|
144
151
|
dict: The configuration of the plot widget.
|
145
152
|
"""
|
@@ -112,9 +112,7 @@ class BECDispatcher:
|
|
112
112
|
cls._initialized = False
|
113
113
|
|
114
114
|
def connect_slot(
|
115
|
-
self,
|
116
|
-
slot: Callable,
|
117
|
-
topics: Union[EndpointInfo, str, list[Union[EndpointInfo, str]]],
|
115
|
+
self, slot: Callable, topics: Union[EndpointInfo, str, list[Union[EndpointInfo, str]]]
|
118
116
|
) -> None:
|
119
117
|
"""Connect widget's pyqt slot, so that it is called on new pub/sub topic message.
|
120
118
|
|
bec_widgets/utils/bec_table.py
CHANGED
@@ -10,6 +10,7 @@ class WidgetContainerUtils:
|
|
10
10
|
def generate_unique_widget_id(container: dict, prefix: str = "widget") -> str:
|
11
11
|
"""
|
12
12
|
Generate a unique widget ID.
|
13
|
+
|
13
14
|
Args:
|
14
15
|
container(dict): The container of widgets.
|
15
16
|
prefix(str): The prefix of the widget ID.
|
@@ -29,10 +30,12 @@ class WidgetContainerUtils:
|
|
29
30
|
) -> QWidget | None:
|
30
31
|
"""
|
31
32
|
Find the first widget of a given class in the figure.
|
33
|
+
|
32
34
|
Args:
|
33
35
|
container(dict): The container of widgets.
|
34
36
|
widget_class(Type): The class of the widget to find.
|
35
37
|
can_fail(bool): If True, the method will return None if no widget is found. If False, it will raise an error.
|
38
|
+
|
36
39
|
Returns:
|
37
40
|
widget: The widget of the given class.
|
38
41
|
"""
|
bec_widgets/utils/crosshair.py
CHANGED
@@ -17,6 +17,7 @@ class Crosshair(QObject):
|
|
17
17
|
def __init__(self, plot_item: pg.PlotItem, precision: int = None, parent=None):
|
18
18
|
"""
|
19
19
|
Crosshair for 1D and 2D plots.
|
20
|
+
|
20
21
|
Args:
|
21
22
|
plot_item (pyqtgraph.PlotItem): The plot item to which the crosshair will be attached.
|
22
23
|
precision (int, optional): Number of decimal places to round the coordinates to. Defaults to None.
|
@@ -5,6 +5,7 @@ class EntryValidator:
|
|
5
5
|
def validate_signal(self, name: str, entry: str = None) -> str:
|
6
6
|
"""
|
7
7
|
Validate a signal entry for a given device. If the entry is not provided, the first signal entry will be used from the device hints.
|
8
|
+
|
8
9
|
Args:
|
9
10
|
name(str): Device name
|
10
11
|
entry(str): Signal entry
|
@@ -28,6 +29,7 @@ class EntryValidator:
|
|
28
29
|
def validate_monitor(self, monitor: str) -> str:
|
29
30
|
"""
|
30
31
|
Validate a monitor entry for a given device.
|
32
|
+
|
31
33
|
Args:
|
32
34
|
monitor(str): Monitor entry
|
33
35
|
|
@@ -21,6 +21,7 @@ class GridLayoutManager:
|
|
21
21
|
def is_position_occupied(self, row: int, col: int) -> bool:
|
22
22
|
"""
|
23
23
|
Check if the position in the layout is occupied by a widget.
|
24
|
+
|
24
25
|
Args:
|
25
26
|
row(int): The row to check.
|
26
27
|
col(int): The column to check.
|
@@ -42,6 +43,7 @@ class GridLayoutManager:
|
|
42
43
|
):
|
43
44
|
"""
|
44
45
|
Shift widgets in the layout in the specified direction starting from the specified position.
|
46
|
+
|
45
47
|
Args:
|
46
48
|
direction(str): The direction to shift the widgets. Can be "down", "up", "left", or "right".
|
47
49
|
start_row(int): The row to start shifting from. Default is 0.
|
@@ -63,6 +65,7 @@ class GridLayoutManager:
|
|
63
65
|
def move_widget(self, widget: QWidget, new_row: int, new_col: int):
|
64
66
|
"""
|
65
67
|
Move a widget to a new position in the layout.
|
68
|
+
|
66
69
|
Args:
|
67
70
|
widget(QWidget): The widget to move.
|
68
71
|
new_row(int): The new row to move the widget to.
|
@@ -82,6 +85,7 @@ class GridLayoutManager:
|
|
82
85
|
):
|
83
86
|
"""
|
84
87
|
Add a widget to the layout at the specified position.
|
88
|
+
|
85
89
|
Args:
|
86
90
|
widget(QWidget): The widget to add.
|
87
91
|
row(int): The row to add the widget to. If None, the widget will be added to the next available row.
|
bec_widgets/utils/widget_io.py
CHANGED
@@ -114,6 +114,7 @@ class WidgetIO:
|
|
114
114
|
def get_value(widget, ignore_errors=False):
|
115
115
|
"""
|
116
116
|
Retrieve value from the widget instance.
|
117
|
+
|
117
118
|
Args:
|
118
119
|
widget: Widget instance.
|
119
120
|
ignore_errors(bool, optional): Whether to ignore if no handler is found.
|
@@ -129,6 +130,7 @@ class WidgetIO:
|
|
129
130
|
def set_value(widget, value, ignore_errors=False):
|
130
131
|
"""
|
131
132
|
Set a value on the widget instance.
|
133
|
+
|
132
134
|
Args:
|
133
135
|
widget: Widget instance.
|
134
136
|
value: Value to set.
|
@@ -155,6 +157,7 @@ class WidgetHierarchy:
|
|
155
157
|
) -> None:
|
156
158
|
"""
|
157
159
|
Print the widget hierarchy to the console.
|
160
|
+
|
158
161
|
Args:
|
159
162
|
widget: Widget to print the hierarchy of
|
160
163
|
indent(int, optional): Level of indentation.
|
@@ -196,6 +199,7 @@ class WidgetHierarchy:
|
|
196
199
|
) -> dict:
|
197
200
|
"""
|
198
201
|
Export the widget hierarchy to a dictionary.
|
202
|
+
|
199
203
|
Args:
|
200
204
|
widget: Widget to print the hierarchy of.
|
201
205
|
config(dict,optional): Dictionary to export the hierarchy to.
|
@@ -245,6 +249,7 @@ class WidgetHierarchy:
|
|
245
249
|
def import_config_from_dict(widget, config: dict, set_values: bool = False) -> None:
|
246
250
|
"""
|
247
251
|
Import the widget hierarchy from a dictionary.
|
252
|
+
|
248
253
|
Args:
|
249
254
|
widget: Widget to import the hierarchy to.
|
250
255
|
config:
|
bec_widgets/utils/yaml_dialog.py
CHANGED
@@ -9,6 +9,7 @@ from qtpy.QtWidgets import QFileDialog
|
|
9
9
|
def load_yaml(instance) -> Union[dict, None]:
|
10
10
|
"""
|
11
11
|
Load YAML file from disk.
|
12
|
+
|
12
13
|
Args:
|
13
14
|
instance: Instance of the calling widget.
|
14
15
|
|
@@ -40,6 +41,7 @@ def load_yaml(instance) -> Union[dict, None]:
|
|
40
41
|
def save_yaml(instance, config: dict) -> None:
|
41
42
|
"""
|
42
43
|
Save YAML file to disk.
|
44
|
+
|
43
45
|
Args:
|
44
46
|
instance: Instance of the calling widget.
|
45
47
|
config: Configuration data to be saved.
|
@@ -8,7 +8,7 @@ class Signal(BaseModel):
|
|
8
8
|
"""
|
9
9
|
Represents a signal in a plot configuration.
|
10
10
|
|
11
|
-
|
11
|
+
Args:
|
12
12
|
name (str): The name of the signal.
|
13
13
|
entry (Optional[str]): The entry point of the signal, optional.
|
14
14
|
"""
|
@@ -21,6 +21,7 @@ class Signal(BaseModel):
|
|
21
21
|
def validate_fields(cls, values):
|
22
22
|
"""Validate the fields of the model.
|
23
23
|
First validate the 'name' field, then validate the 'entry' field.
|
24
|
+
|
24
25
|
Args:
|
25
26
|
values (dict): The values to be validated."""
|
26
27
|
devices = MonitorConfigValidator.devices
|
@@ -70,13 +70,11 @@ class BECDockArea(BECConnector, DockArea):
|
|
70
70
|
self.docks = WeakValueDictionary(value)
|
71
71
|
|
72
72
|
def restore_state(
|
73
|
-
self,
|
74
|
-
state: dict = None,
|
75
|
-
missing: Literal["ignore", "error"] = "ignore",
|
76
|
-
extra="bottom",
|
73
|
+
self, state: dict = None, missing: Literal["ignore", "error"] = "ignore", extra="bottom"
|
77
74
|
):
|
78
75
|
"""
|
79
76
|
Restore the state of the dock area. If no state is provided, the last state is restored.
|
77
|
+
|
80
78
|
Args:
|
81
79
|
state(dict): The state to restore.
|
82
80
|
missing(Literal['ignore','error']): What to do if a dock is missing.
|
@@ -89,6 +87,7 @@ class BECDockArea(BECConnector, DockArea):
|
|
89
87
|
def save_state(self) -> dict:
|
90
88
|
"""
|
91
89
|
Save the state of the dock area.
|
90
|
+
|
92
91
|
Returns:
|
93
92
|
dict: The state of the dock area.
|
94
93
|
"""
|
@@ -98,6 +97,7 @@ class BECDockArea(BECConnector, DockArea):
|
|
98
97
|
def remove_dock(self, name: str):
|
99
98
|
"""
|
100
99
|
Remove a dock by name and ensure it is properly closed and cleaned up.
|
100
|
+
|
101
101
|
Args:
|
102
102
|
name(str): The name of the dock to remove.
|
103
103
|
"""
|
@@ -138,6 +138,7 @@ class BECDockArea(BECConnector, DockArea):
|
|
138
138
|
col(int): The column of the added widget.
|
139
139
|
rowspan(int): The rowspan of the added widget.
|
140
140
|
colspan(int): The colspan of the added widget.
|
141
|
+
|
141
142
|
Returns:
|
142
143
|
BECDock: The created dock.
|
143
144
|
"""
|
@@ -178,6 +179,7 @@ class BECDockArea(BECConnector, DockArea):
|
|
178
179
|
def detach_dock(self, dock_name: str) -> BECDock:
|
179
180
|
"""
|
180
181
|
Undock a dock from the dock area.
|
182
|
+
|
181
183
|
Args:
|
182
184
|
dock_name(str): The dock to undock.
|
183
185
|
|