bec-widgets 0.57.0__py3-none-any.whl → 0.57.2__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.
- CHANGELOG.md +32 -40
- PKG-INFO +2 -1
- bec_widgets/cli/auto_updates.py +1 -1
- bec_widgets/cli/client.py +14 -4
- bec_widgets/cli/client_utils.py +48 -49
- bec_widgets/examples/jupyter_console/jupyter_console_window.py +4 -4
- bec_widgets/widgets/dock/dock.py +44 -35
- bec_widgets/widgets/dock/dock_area.py +18 -5
- bec_widgets/widgets/figure/plots/motor_map/motor_map.py +2 -2
- bec_widgets/widgets/figure/plots/waveform/waveform.py +0 -1
- bec_widgets/widgets/spiral_progress_bar/ring.py +2 -1
- {bec_widgets-0.57.0.dist-info → bec_widgets-0.57.2.dist-info}/METADATA +2 -1
- {bec_widgets-0.57.0.dist-info → bec_widgets-0.57.2.dist-info}/RECORD +23 -23
- docs/user/widgets/bec_figure.md +4 -4
- docs/user/widgets/spiral_progress_bar.md +2 -2
- pyproject.toml +2 -1
- tests/end-2-end/conftest.py +41 -26
- tests/end-2-end/test_bec_dock_rpc_e2e.py +72 -94
- tests/end-2-end/test_bec_figure_rpc_e2e.py +18 -30
- tests/end-2-end/test_rpc_register_e2e.py +16 -26
- tests/unit_tests/test_bec_dock.py +1 -1
- {bec_widgets-0.57.0.dist-info → bec_widgets-0.57.2.dist-info}/WHEEL +0 -0
- {bec_widgets-0.57.0.dist-info → bec_widgets-0.57.2.dist-info}/licenses/LICENSE +0 -0
CHANGELOG.md
CHANGED
@@ -2,6 +2,38 @@
|
|
2
2
|
|
3
3
|
|
4
4
|
|
5
|
+
## v0.57.2 (2024-06-06)
|
6
|
+
|
7
|
+
### Fix
|
8
|
+
|
9
|
+
* fix(test/e2e): autoupdate e2e rewritten ([`e1af5ca`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/e1af5ca60f0616835f9f41d84412f29dc298c644))
|
10
|
+
|
11
|
+
* fix(test/e2e): spiral_progress_bar e2e tests rewritten to use config_dict ([`7fb31fc`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/7fb31fc4d762ff4ca839971b3092a084186f81b8))
|
12
|
+
|
13
|
+
* fix(test/e2e): dockarea and dock e2e tests changed to check asserts against config_dict ([`5c6ba65`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/5c6ba65469863ea1e6fc5abdc742650e20eba9b9))
|
14
|
+
|
15
|
+
* fix: rpc_server_dock fixture now spawns the server process ([`cd9fc46`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/cd9fc46ff8a947242c8c28adcd73d7de60b11c44))
|
16
|
+
|
17
|
+
* fix: accept scalars or numpy arrays of 1 element ([`2a88e17`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/2a88e17b23436c55d25b7d3449e4af3a7689661c))
|
18
|
+
|
19
|
+
### Refactor
|
20
|
+
|
21
|
+
* refactor: move _get_output and _start_plot_process at the module level ([`69f4371`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/69f4371007c66aee6b7521a6803054025adf8c92))
|
22
|
+
|
23
|
+
|
24
|
+
## v0.57.1 (2024-06-06)
|
25
|
+
|
26
|
+
### Documentation
|
27
|
+
|
28
|
+
* docs: docs refactored from add_widget_bec to add_widget ([`c3f4845`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/c3f4845b4f95005ff737fed5542600b0b9a9cc2b))
|
29
|
+
|
30
|
+
### Fix
|
31
|
+
|
32
|
+
* fix: tests references to add_widget_bec refactored ([`f51b25f`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/f51b25f0af4ab8b0a75ee48a40bfbb079c16e9d1))
|
33
|
+
|
34
|
+
* fix(dock): add_widget and add_widget_bec consolidated ([`8ae323f`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/8ae323f5c3c0d9d0f202d31d5e8374a272a26be2))
|
35
|
+
|
36
|
+
|
5
37
|
## v0.57.0 (2024-06-05)
|
6
38
|
|
7
39
|
### Documentation
|
@@ -133,43 +165,3 @@
|
|
133
165
|
|
134
166
|
|
135
167
|
## v0.53.0 (2024-05-09)
|
136
|
-
|
137
|
-
### Ci
|
138
|
-
|
139
|
-
* ci: use formatter config of toml file ([`5cc816d`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/5cc816d0af73e20c648e044a027c589704ab1625))
|
140
|
-
|
141
|
-
### Documentation
|
142
|
-
|
143
|
-
* docs: update install instructions ([`57ee735`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/57ee735e5c2436d45a285507cdc939daa20e8e8f))
|
144
|
-
|
145
|
-
### Feature
|
146
|
-
|
147
|
-
* feat: moved to pyproject.toml; closes #162 ([`c86ce30`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/c86ce302a964d71ee631f0817609ab5aa0e3ab0f))
|
148
|
-
|
149
|
-
### Fix
|
150
|
-
|
151
|
-
* fix: fixed semver job and upgraded to v9 ([`32e1a9d`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/32e1a9d8472eb1c25d30697d407a8ffecd04e75d))
|
152
|
-
|
153
|
-
### Refactor
|
154
|
-
|
155
|
-
* refactor: applied formatter ([`4117fd7`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/4117fd7b5b2090ff4fb7ad9e0d92cc87cd13ed5f))
|
156
|
-
|
157
|
-
|
158
|
-
## v0.52.1 (2024-05-08)
|
159
|
-
|
160
|
-
### Fix
|
161
|
-
|
162
|
-
* fix(docstrings): docstrings formating fixed for sphinx to properly format readdocs ([`7f2f7cd`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/7f2f7cd07a14876617cd83cedde8c281fdc52c3a))
|
163
|
-
|
164
|
-
|
165
|
-
## v0.52.0 (2024-05-07)
|
166
|
-
|
167
|
-
### Feature
|
168
|
-
|
169
|
-
* feat(utils/layout_manager): added GridLayoutManager to extend functionalities of native QGridLayout ([`fcd6ef0`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/fcd6ef0975dc872f69c9d6fb2b8a1ad04a423aae))
|
170
|
-
|
171
|
-
* feat(widget/dock): BECDock and BECDock area for dockable windows ([`d8ff8af`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/d8ff8afcd474660a6069bbdab05f10a65f221727))
|
172
|
-
|
173
|
-
### Fix
|
174
|
-
|
175
|
-
* fix(widgets/dock): BECDockArea close overwrites the default pyqtgraph Container close + minor improvements ([`ceae979`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/ceae979f375ecc33c5c97148f197655c1ca57b6c))
|
PKG-INFO
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: bec_widgets
|
3
|
-
Version: 0.57.
|
3
|
+
Version: 0.57.2
|
4
4
|
Summary: BEC Widgets
|
5
5
|
Project-URL: Bug Tracker, https://gitlab.psi.ch/bec/bec_widgets/issues
|
6
6
|
Project-URL: Homepage, https://gitlab.psi.ch/bec/bec_widgets
|
@@ -27,6 +27,7 @@ Requires-Dist: pytest; extra == 'dev'
|
|
27
27
|
Requires-Dist: pytest-qt; extra == 'dev'
|
28
28
|
Requires-Dist: pytest-random-order; extra == 'dev'
|
29
29
|
Requires-Dist: pytest-timeout; extra == 'dev'
|
30
|
+
Requires-Dist: pytest-xvfb; extra == 'dev'
|
30
31
|
Provides-Extra: pyqt5
|
31
32
|
Requires-Dist: pyqt5>=5.9; extra == 'pyqt5'
|
32
33
|
Provides-Extra: pyqt6
|
bec_widgets/cli/auto_updates.py
CHANGED
bec_widgets/cli/client.py
CHANGED
@@ -1468,20 +1468,20 @@ class BECDock(RPCBase):
|
|
1468
1468
|
"""
|
1469
1469
|
|
1470
1470
|
@rpc_call
|
1471
|
-
def
|
1471
|
+
def add_widget(
|
1472
1472
|
self,
|
1473
|
-
|
1473
|
+
widget: "BECConnector | str",
|
1474
1474
|
row=None,
|
1475
1475
|
col=0,
|
1476
1476
|
rowspan=1,
|
1477
1477
|
colspan=1,
|
1478
1478
|
shift: "Literal['down', 'up', 'left', 'right']" = "down",
|
1479
|
-
):
|
1479
|
+
) -> "BECConnector":
|
1480
1480
|
"""
|
1481
1481
|
Add a widget to the dock.
|
1482
1482
|
|
1483
1483
|
Args:
|
1484
|
-
|
1484
|
+
widget(QWidget): The widget to add.
|
1485
1485
|
row(int): The row to add the widget to. If None, the widget will be added to the next available row.
|
1486
1486
|
col(int): The column to add the widget to.
|
1487
1487
|
rowspan(int): The number of rows the widget should span.
|
@@ -1651,6 +1651,16 @@ class BECDockArea(RPCBase, BECGuiClientMixin):
|
|
1651
1651
|
Get all registered RPC objects.
|
1652
1652
|
"""
|
1653
1653
|
|
1654
|
+
@property
|
1655
|
+
@rpc_call
|
1656
|
+
def temp_areas(self) -> "list":
|
1657
|
+
"""
|
1658
|
+
Get the temporary areas in the dock area.
|
1659
|
+
|
1660
|
+
Returns:
|
1661
|
+
list: The temporary areas in the dock area.
|
1662
|
+
"""
|
1663
|
+
|
1654
1664
|
|
1655
1665
|
class SpiralProgressBar(RPCBase):
|
1656
1666
|
@rpc_call
|
bec_widgets/cli/client_utils.py
CHANGED
@@ -61,10 +61,54 @@ def rpc_call(func):
|
|
61
61
|
return wrapper
|
62
62
|
|
63
63
|
|
64
|
+
def _get_output(process) -> None:
|
65
|
+
try:
|
66
|
+
os.set_blocking(process.stdout.fileno(), False)
|
67
|
+
os.set_blocking(process.stderr.fileno(), False)
|
68
|
+
while process.poll() is None:
|
69
|
+
readylist, _, _ = select.select([process.stdout, process.stderr], [], [], 1)
|
70
|
+
if process.stdout in readylist:
|
71
|
+
output = process.stdout.read(1024)
|
72
|
+
if output:
|
73
|
+
print(output, end="")
|
74
|
+
if process.stderr in readylist:
|
75
|
+
error_output = process.stderr.read(1024)
|
76
|
+
if error_output:
|
77
|
+
print(error_output, end="", file=sys.stderr)
|
78
|
+
except Exception as e:
|
79
|
+
print(f"Error reading process output: {str(e)}")
|
80
|
+
|
81
|
+
|
82
|
+
def _start_plot_process(gui_id, gui_class, config) -> None:
|
83
|
+
"""
|
84
|
+
Start the plot in a new process.
|
85
|
+
"""
|
86
|
+
# pylint: disable=subprocess-run-check
|
87
|
+
monitor_module = importlib.import_module("bec_widgets.cli.server")
|
88
|
+
monitor_path = monitor_module.__file__
|
89
|
+
|
90
|
+
command = [
|
91
|
+
sys.executable,
|
92
|
+
"-u",
|
93
|
+
monitor_path,
|
94
|
+
"--id",
|
95
|
+
gui_id,
|
96
|
+
"--config",
|
97
|
+
config,
|
98
|
+
"--gui_class",
|
99
|
+
gui_class.__name__,
|
100
|
+
]
|
101
|
+
process = subprocess.Popen(command, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
102
|
+
process_output_processing_thread = threading.Thread(target=_get_output, args=(process,))
|
103
|
+
process_output_processing_thread.start()
|
104
|
+
return process, process_output_processing_thread
|
105
|
+
|
106
|
+
|
64
107
|
class BECGuiClientMixin:
|
65
108
|
def __init__(self, **kwargs) -> None:
|
66
109
|
super().__init__(**kwargs)
|
67
110
|
self._process = None
|
111
|
+
self._process_output_processing_thread = None
|
68
112
|
self.auto_updates = self._get_update_script()
|
69
113
|
self._target_endpoint = MessageEndpoints.scan_status()
|
70
114
|
self._selected_device = None
|
@@ -118,7 +162,10 @@ class BECGuiClientMixin:
|
|
118
162
|
Show the figure.
|
119
163
|
"""
|
120
164
|
if self._process is None or self._process.poll() is not None:
|
121
|
-
self.
|
165
|
+
self._start_update_script()
|
166
|
+
self._process, self._process_output_processing_thread = _start_plot_process(
|
167
|
+
self._gui_id, self.__class__, self._client._service_config.redis
|
168
|
+
)
|
122
169
|
while not self.gui_is_alive():
|
123
170
|
print("Waiting for GUI to start...")
|
124
171
|
time.sleep(1)
|
@@ -138,34 +185,6 @@ class BECGuiClientMixin:
|
|
138
185
|
self._process = None
|
139
186
|
self._client.shutdown()
|
140
187
|
|
141
|
-
def _start_plot_process(self) -> None:
|
142
|
-
"""
|
143
|
-
Start the plot in a new process.
|
144
|
-
"""
|
145
|
-
self._start_update_script()
|
146
|
-
# pylint: disable=subprocess-run-check
|
147
|
-
config = self._client._service_config.redis
|
148
|
-
monitor_module = importlib.import_module("bec_widgets.cli.server")
|
149
|
-
monitor_path = monitor_module.__file__
|
150
|
-
gui_class = self.__class__.__name__
|
151
|
-
|
152
|
-
command = [
|
153
|
-
sys.executable,
|
154
|
-
"-u",
|
155
|
-
monitor_path,
|
156
|
-
"--id",
|
157
|
-
self._gui_id,
|
158
|
-
"--config",
|
159
|
-
config,
|
160
|
-
"--gui_class",
|
161
|
-
gui_class,
|
162
|
-
]
|
163
|
-
self._process = subprocess.Popen(
|
164
|
-
command, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
165
|
-
)
|
166
|
-
self._process_output_processing_thread = threading.Thread(target=self._get_output)
|
167
|
-
self._process_output_processing_thread.start()
|
168
|
-
|
169
188
|
def print_log(self) -> None:
|
170
189
|
"""
|
171
190
|
Print the log of the plot process.
|
@@ -176,26 +195,6 @@ class BECGuiClientMixin:
|
|
176
195
|
# Flush list
|
177
196
|
self.stderr_output.clear()
|
178
197
|
|
179
|
-
def _get_output(self) -> str:
|
180
|
-
try:
|
181
|
-
os.set_blocking(self._process.stdout.fileno(), False)
|
182
|
-
os.set_blocking(self._process.stderr.fileno(), False)
|
183
|
-
while self._process.poll() is None:
|
184
|
-
readylist, _, _ = select.select(
|
185
|
-
[self._process.stdout, self._process.stderr], [], [], 1
|
186
|
-
)
|
187
|
-
if self._process.stdout in readylist:
|
188
|
-
output = self._process.stdout.read(1024)
|
189
|
-
if output:
|
190
|
-
print(output, end="")
|
191
|
-
if self._process.stderr in readylist:
|
192
|
-
error_output = self._process.stderr.read(1024)
|
193
|
-
if error_output:
|
194
|
-
print(error_output, end="", file=sys.stderr)
|
195
|
-
self.stderr_output.append(error_output)
|
196
|
-
except Exception as e:
|
197
|
-
print(f"Error reading process output: {str(e)}")
|
198
|
-
|
199
198
|
|
200
199
|
class RPCResponseTimeoutError(Exception):
|
201
200
|
"""Exception raised when an RPC response is not received within the expected time."""
|
@@ -104,19 +104,19 @@ class JupyterConsoleWindow(QWidget): # pragma: no cover:
|
|
104
104
|
def _init_dock(self):
|
105
105
|
|
106
106
|
self.d0 = self.dock.add_dock(name="dock_0")
|
107
|
-
self.fig0 = self.d0.
|
107
|
+
self.fig0 = self.d0.add_widget("BECFigure")
|
108
108
|
self.fig0.image("eiger", vrange=(0, 100))
|
109
109
|
|
110
110
|
self.d1 = self.dock.add_dock(name="dock_1", position="right")
|
111
|
-
self.fig1 = self.d1.
|
111
|
+
self.fig1 = self.d1.add_widget("BECFigure")
|
112
112
|
self.fig1.plot(x_name="samx", y_name="bpm4i")
|
113
113
|
self.fig1.plot(x_name="samx", y_name="bpm3a")
|
114
114
|
|
115
115
|
self.d2 = self.dock.add_dock(name="dock_2", position="bottom")
|
116
|
-
self.fig2 = self.d2.
|
116
|
+
self.fig2 = self.d2.add_widget("BECFigure", row=0, col=0)
|
117
117
|
self.fig2.motor_map(x_name="samx", y_name="samy")
|
118
118
|
self.fig2.plot(x_name="samx", y_name="bpm4i")
|
119
|
-
self.bar = self.d2.
|
119
|
+
self.bar = self.d2.add_widget("SpiralProgressBar", row=0, col=1)
|
120
120
|
self.bar.set_diameter(200)
|
121
121
|
|
122
122
|
self.dock.save_state()
|
bec_widgets/widgets/dock/dock.py
CHANGED
@@ -33,7 +33,7 @@ class BECDock(BECConnector, Dock):
|
|
33
33
|
"hide_title_bar",
|
34
34
|
"get_widgets_positions",
|
35
35
|
"set_title",
|
36
|
-
"
|
36
|
+
"add_widget",
|
37
37
|
"list_eligible_widgets",
|
38
38
|
"move_widget",
|
39
39
|
"remove_widget",
|
@@ -152,47 +152,47 @@ class BECDock(BECConnector, Dock):
|
|
152
152
|
"""
|
153
153
|
return list(RPCWidgetHandler.widget_classes.keys())
|
154
154
|
|
155
|
-
def add_widget_bec(
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
):
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
155
|
+
# def add_widget_bec(
|
156
|
+
# self,
|
157
|
+
# widget_type: str,
|
158
|
+
# row=None,
|
159
|
+
# col=0,
|
160
|
+
# rowspan=1,
|
161
|
+
# colspan=1,
|
162
|
+
# shift: Literal["down", "up", "left", "right"] = "down",
|
163
|
+
# ):
|
164
|
+
# """
|
165
|
+
# Add a widget to the dock.
|
166
|
+
#
|
167
|
+
# Args:
|
168
|
+
# widget_type(str): The widget to add. Only BEC RPC widgets from RPCWidgetHandler are allowed.
|
169
|
+
# row(int): The row to add the widget to. If None, the widget will be added to the next available row.
|
170
|
+
# col(int): The column to add the widget to.
|
171
|
+
# rowspan(int): The number of rows the widget should span.
|
172
|
+
# colspan(int): The number of columns the widget should span.
|
173
|
+
# shift(Literal["down", "up", "left", "right"]): The direction to shift the widgets if the position is occupied.
|
174
|
+
# """
|
175
|
+
# if row is None:
|
176
|
+
# row = self.layout.rowCount()
|
177
|
+
#
|
178
|
+
# if self.layout_manager.is_position_occupied(row, col):
|
179
|
+
# self.layout_manager.shift_widgets(shift, start_row=row)
|
180
|
+
#
|
181
|
+
# widget = RPCWidgetHandler.create_widget(widget_type)
|
182
|
+
# self.addWidget(widget, row=row, col=col, rowspan=rowspan, colspan=colspan)
|
183
|
+
# self.config.widgets[widget.gui_id] = widget.config
|
184
|
+
#
|
185
|
+
# return widget
|
186
186
|
|
187
187
|
def add_widget(
|
188
188
|
self,
|
189
|
-
widget:
|
189
|
+
widget: BECConnector | str,
|
190
190
|
row=None,
|
191
191
|
col=0,
|
192
192
|
rowspan=1,
|
193
193
|
colspan=1,
|
194
194
|
shift: Literal["down", "up", "left", "right"] = "down",
|
195
|
-
):
|
195
|
+
) -> BECConnector:
|
196
196
|
"""
|
197
197
|
Add a widget to the dock.
|
198
198
|
|
@@ -210,8 +210,17 @@ class BECDock(BECConnector, Dock):
|
|
210
210
|
if self.layout_manager.is_position_occupied(row, col):
|
211
211
|
self.layout_manager.shift_widgets(shift, start_row=row)
|
212
212
|
|
213
|
+
if isinstance(widget, str):
|
214
|
+
widget = RPCWidgetHandler.create_widget(widget)
|
215
|
+
else:
|
216
|
+
widget = widget
|
217
|
+
|
213
218
|
self.addWidget(widget, row=row, col=col, rowspan=rowspan, colspan=colspan)
|
214
|
-
|
219
|
+
|
220
|
+
if hasattr(widget, "config"):
|
221
|
+
self.config.widgets[widget.gui_id] = widget.config
|
222
|
+
|
223
|
+
return widget
|
215
224
|
|
216
225
|
def move_widget(self, widget: QWidget, new_row: int, new_col: int):
|
217
226
|
"""
|
@@ -33,6 +33,7 @@ class BECDockArea(BECConnector, DockArea):
|
|
33
33
|
"detach_dock",
|
34
34
|
"attach_all",
|
35
35
|
"get_all_rpc",
|
36
|
+
"temp_areas",
|
36
37
|
]
|
37
38
|
|
38
39
|
def __init__(
|
@@ -70,9 +71,22 @@ class BECDockArea(BECConnector, DockArea):
|
|
70
71
|
|
71
72
|
@panels.setter
|
72
73
|
def panels(self, value: dict):
|
73
|
-
|
74
74
|
self.docks = WeakValueDictionary(value)
|
75
75
|
|
76
|
+
@property
|
77
|
+
def temp_areas(self) -> list:
|
78
|
+
"""
|
79
|
+
Get the temporary areas in the dock area.
|
80
|
+
|
81
|
+
Returns:
|
82
|
+
list: The temporary areas in the dock area.
|
83
|
+
"""
|
84
|
+
return list(map(str, self.tempAreas))
|
85
|
+
|
86
|
+
@temp_areas.setter
|
87
|
+
def temp_areas(self, value: list):
|
88
|
+
self.tempAreas = list(map(str, value))
|
89
|
+
|
76
90
|
def restore_state(
|
77
91
|
self, state: dict = None, missing: Literal["ignore", "error"] = "ignore", extra="bottom"
|
78
92
|
):
|
@@ -107,6 +121,7 @@ class BECDockArea(BECConnector, DockArea):
|
|
107
121
|
name(str): The name of the dock to remove.
|
108
122
|
"""
|
109
123
|
dock = self.docks.pop(name, None)
|
124
|
+
self.config.docks.pop(name, None)
|
110
125
|
if dock:
|
111
126
|
dock.close()
|
112
127
|
if len(self.docks) <= 1:
|
@@ -171,9 +186,7 @@ class BECDockArea(BECConnector, DockArea):
|
|
171
186
|
dock.show_title_bar()
|
172
187
|
|
173
188
|
if widget is not None and isinstance(widget, str):
|
174
|
-
dock.
|
175
|
-
widget_type=widget, row=row, col=col, rowspan=rowspan, colspan=colspan
|
176
|
-
)
|
189
|
+
dock.add_widget(widget=widget, row=row, col=col, rowspan=rowspan, colspan=colspan)
|
177
190
|
elif widget is not None and isinstance(widget, QWidget):
|
178
191
|
dock.addWidget(widget, row=row, col=col, rowspan=rowspan, colspan=colspan)
|
179
192
|
if self._instructions_visible:
|
@@ -192,7 +205,7 @@ class BECDockArea(BECConnector, DockArea):
|
|
192
205
|
BECDock: The undocked dock.
|
193
206
|
"""
|
194
207
|
dock = self.docks[dock_name]
|
195
|
-
|
208
|
+
dock.detach()
|
196
209
|
return dock
|
197
210
|
|
198
211
|
def attach_all(self):
|
@@ -317,7 +317,7 @@ class BECMotorMap(BECPlotBase):
|
|
317
317
|
Returns:
|
318
318
|
float: Motor initial position.
|
319
319
|
"""
|
320
|
-
init_position = round(self.dev[name].read()[entry]["value"], precision)
|
320
|
+
init_position = round(float(self.dev[name].read()[entry]["value"]), precision)
|
321
321
|
return init_position
|
322
322
|
|
323
323
|
def _validate_signal_entries(
|
@@ -403,7 +403,7 @@ class BECMotorMap(BECPlotBase):
|
|
403
403
|
# Update plot title
|
404
404
|
precision = self.config.precision
|
405
405
|
self.set_title(
|
406
|
-
f"Motor position: ({round(current_x,precision)}, {round(current_y,precision)})"
|
406
|
+
f"Motor position: ({round(float(current_x),precision)}, {round(float(current_y),precision)})"
|
407
407
|
)
|
408
408
|
|
409
409
|
@pyqtSlot(dict)
|
@@ -115,7 +115,8 @@ class Ring(BECConnector):
|
|
115
115
|
|
116
116
|
def set_value(self, value: int | float):
|
117
117
|
self.config.value = round(
|
118
|
-
max(self.config.min_value, min(self.config.max_value, value)),
|
118
|
+
float(max(self.config.min_value, min(self.config.max_value, value))),
|
119
|
+
self.config.precision,
|
119
120
|
)
|
120
121
|
|
121
122
|
def set_color(self, color: str | tuple):
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: bec_widgets
|
3
|
-
Version: 0.57.
|
3
|
+
Version: 0.57.2
|
4
4
|
Summary: BEC Widgets
|
5
5
|
Project-URL: Bug Tracker, https://gitlab.psi.ch/bec/bec_widgets/issues
|
6
6
|
Project-URL: Homepage, https://gitlab.psi.ch/bec/bec_widgets
|
@@ -27,6 +27,7 @@ Requires-Dist: pytest; extra == 'dev'
|
|
27
27
|
Requires-Dist: pytest-qt; extra == 'dev'
|
28
28
|
Requires-Dist: pytest-random-order; extra == 'dev'
|
29
29
|
Requires-Dist: pytest-timeout; extra == 'dev'
|
30
|
+
Requires-Dist: pytest-xvfb; extra == 'dev'
|
30
31
|
Provides-Extra: pyqt5
|
31
32
|
Requires-Dist: pyqt5>=5.9; extra == 'pyqt5'
|
32
33
|
Provides-Extra: pyqt6
|
@@ -2,11 +2,11 @@
|
|
2
2
|
.gitlab-ci.yml,sha256=RF2JeGh8tG09DyAOwEu991IZy3C8Vm6lI8O_4Dr9B9Q,12239
|
3
3
|
.pylintrc,sha256=OstrgmEyP0smNFBKoIN5_26-UmNZgMHnbjvAWX0UrLs,18535
|
4
4
|
.readthedocs.yaml,sha256=aSOc277LqXcsTI6lgvm_JY80lMlr69GbPKgivua2cS0,603
|
5
|
-
CHANGELOG.md,sha256=
|
5
|
+
CHANGELOG.md,sha256=pG4sxxA4UKrOCZsHzC7nzYA5A7dwla6lFKnMujn04rQ,6889
|
6
6
|
LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
|
7
|
-
PKG-INFO,sha256=
|
7
|
+
PKG-INFO,sha256=VKjVy_MzeMyq50c2kmwfQ9hoe6abecAZIR6nSJcwVck,1178
|
8
8
|
README.md,sha256=y4jB6wvArS7N8_iTbKWnSM_oRAqLA2GqgzUR-FMh5sU,2645
|
9
|
-
pyproject.toml,sha256=
|
9
|
+
pyproject.toml,sha256=mYnyN3JxG1ULTqPhRsHj5xvuD0wUNtZydA6gaSddQSE,1822
|
10
10
|
.git_hooks/pre-commit,sha256=n3RofIZHJl8zfJJIUomcMyYGFi_rwq4CC19z0snz3FI,286
|
11
11
|
.gitlab/issue_templates/bug_report_template.md,sha256=gAuyEwl7XlnebBrkiJ9AqffSNOywmr8vygUFWKTuQeI,386
|
12
12
|
.gitlab/issue_templates/documentation_update_template.md,sha256=FHLdb3TS_D9aL4CYZCjyXSulbaW5mrN2CmwTaeLPbNw,860
|
@@ -16,16 +16,16 @@ bec_widgets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
16
|
bec_widgets/assets/bec_widgets_icon.png,sha256=K8dgGwIjalDh9PRHUsSQBqgdX7a00nM3igZdc20pkYM,1747017
|
17
17
|
bec_widgets/assets/terminal_icon.png,sha256=bJl7Tft4Fi2uxvuXI8o14uMHnI9eAWKSU2uftXCH9ws,3889
|
18
18
|
bec_widgets/cli/__init__.py,sha256=tLD8HWgyURhMjYlKZ43pBu-qvGD1LI5o3n3rEieg-70,43
|
19
|
-
bec_widgets/cli/auto_updates.py,sha256=
|
20
|
-
bec_widgets/cli/client.py,sha256=
|
21
|
-
bec_widgets/cli/client_utils.py,sha256=
|
19
|
+
bec_widgets/cli/auto_updates.py,sha256=8x4_SrD8Hh1RbrUWXLfisw6X5v8Mij2DiTfjvn9dkUw,4692
|
20
|
+
bec_widgets/cli/client.py,sha256=DaBkuNB38XhOdNuAmd7UPaEy4kEWCgOdWWfMsPBsWAI,53089
|
21
|
+
bec_widgets/cli/client_utils.py,sha256=7u8P9EYgLPJuAcHxnFiZi-gCZohO3vAn0W7dqsSrs4M,10660
|
22
22
|
bec_widgets/cli/generate_cli.py,sha256=tBt-F4Xccg9Pj2zuDEGHd0Ho1fKLfCf3PuSa8KmelQk,4431
|
23
23
|
bec_widgets/cli/rpc_register.py,sha256=QxXUZu5XNg00Yf5O3UHWOXg3-f_pzKjjoZYMOa-MOJc,2216
|
24
24
|
bec_widgets/cli/rpc_wigdet_handler.py,sha256=OXHoiDFJPzbQ5RO0bzIX5aUXeMMlJTwAiTmB0_7Chj4,913
|
25
25
|
bec_widgets/cli/server.py,sha256=rsj31Vsx6ayThNe4PQelQFahGjYXFZjfrNyB2fnm6Ro,5737
|
26
26
|
bec_widgets/examples/__init__.py,sha256=WWQ0cu7m8sA4Ehy-DWdTIqSISjaHsbxhsNmNrMnhDZU,202
|
27
27
|
bec_widgets/examples/jupyter_console/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
28
|
-
bec_widgets/examples/jupyter_console/jupyter_console_window.py,sha256=
|
28
|
+
bec_widgets/examples/jupyter_console/jupyter_console_window.py,sha256=pfwbMfvXu0FdX-a6SdprfOEGxG-IgsuySnYy3l9fwIM,5328
|
29
29
|
bec_widgets/examples/jupyter_console/jupyter_console_window.ui,sha256=2A2mNTUMZBYygz8K4qWzrcjnNqZBMVyeHm26iLZVRWI,1473
|
30
30
|
bec_widgets/examples/motor_movement/__init__.py,sha256=LzPJkxLAxOsZCbXR-fRCPmeYobp7Yqds6tDxW4W1gSw,214
|
31
31
|
bec_widgets/examples/motor_movement/motor_control_compilations.py,sha256=8rpA7a2xVZTDMrx7YQIj3IJew78J1gcVMkHvloS0U_Q,9055
|
@@ -48,8 +48,8 @@ bec_widgets/utils/widget_io.py,sha256=f36198CvT_EzWQ_cg2G-4tRRsaMdJ3yVqsZWKJCQEf
|
|
48
48
|
bec_widgets/utils/yaml_dialog.py,sha256=cMVif-39SB9WjwGH5FWBJcFs4tnfFJFs5cacydRyhy0,1853
|
49
49
|
bec_widgets/widgets/__init__.py,sha256=LKgIuY3CI-NHCa_bY9pThYhxLH0MHDo8iNEJDDVIVmw,172
|
50
50
|
bec_widgets/widgets/dock/__init__.py,sha256=B7foHt02gnhM7mFksa7GJVwT7n0j_JvYDCt6wc6XR5g,61
|
51
|
-
bec_widgets/widgets/dock/dock.py,sha256=
|
52
|
-
bec_widgets/widgets/dock/dock_area.py,sha256=
|
51
|
+
bec_widgets/widgets/dock/dock.py,sha256=kdX0ZbuUdx6XETZ1NUgzBWlee_Q7JcN3fXpARDAlre8,8955
|
52
|
+
bec_widgets/widgets/dock/dock_area.py,sha256=Yj01iI5Lzh-Rf6D9Z4m48JItVHC-1954MJHfjYimEE8,7731
|
53
53
|
bec_widgets/widgets/figure/__init__.py,sha256=3hGx_KOV7QHCYAV06aNuUgKq4QIYCjUTad-DrwkUaBM,44
|
54
54
|
bec_widgets/widgets/figure/figure.py,sha256=OzeKZme89JnzMcKT1sACnyw951EtRoSUALl58upY6b4,29762
|
55
55
|
bec_widgets/widgets/figure/plots/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -59,9 +59,9 @@ bec_widgets/widgets/figure/plots/image/image.py,sha256=fdANm_lMzmKeddwCq3Arc1p48
|
|
59
59
|
bec_widgets/widgets/figure/plots/image/image_item.py,sha256=1oytCY2IIgRbtS3GRrp9JV02KOif78O2-iaK0qYuHFU,9058
|
60
60
|
bec_widgets/widgets/figure/plots/image/image_processor.py,sha256=59JwHMEBjLo72fmrAB7W1PFBT2oBe16heBaZfYM6MAk,4368
|
61
61
|
bec_widgets/widgets/figure/plots/motor_map/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
62
|
-
bec_widgets/widgets/figure/plots/motor_map/motor_map.py,sha256=
|
62
|
+
bec_widgets/widgets/figure/plots/motor_map/motor_map.py,sha256=Ff2WoNHxO_A3ggsbSd_AVUP1JeOWMuJs-0GLskxn-94,15267
|
63
63
|
bec_widgets/widgets/figure/plots/waveform/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
64
|
-
bec_widgets/widgets/figure/plots/waveform/waveform.py,sha256=
|
64
|
+
bec_widgets/widgets/figure/plots/waveform/waveform.py,sha256=U0d4Qdsej9AlHrAf7krgE4AFWEkK_Y-IAGjH-Tv9bT0,21663
|
65
65
|
bec_widgets/widgets/figure/plots/waveform/waveform_curve.py,sha256=9q7nJfyH8y9rWw_AIOd6tk7cbckoAGNLHv2oHEKCCyo,7229
|
66
66
|
bec_widgets/widgets/jupyter_console/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
67
67
|
bec_widgets/widgets/jupyter_console/jupyter_console.py,sha256=ioLYJL31RdBoAOGFSS8PVSnUhkWPWmLC3tiKp7CouO8,2251
|
@@ -82,7 +82,7 @@ bec_widgets/widgets/motor_control/selection/selection.ui,sha256=vXXpvNWuL6xyHhW7
|
|
82
82
|
bec_widgets/widgets/scan_control/__init__.py,sha256=IOfHl15vxb_uC6KN62-PeUzbBha_vQyqkkXbJ2HU674,38
|
83
83
|
bec_widgets/widgets/scan_control/scan_control.py,sha256=B5n2U2iVtTCY3Tx93JyBqzGCDCmWhWwAOhbPelLI-bs,17168
|
84
84
|
bec_widgets/widgets/spiral_progress_bar/__init__.py,sha256=4efbtcqCToMIw5bkQrTzy2TzuBCXvlhuUPh1bYC_Yzg,51
|
85
|
-
bec_widgets/widgets/spiral_progress_bar/ring.py,sha256=
|
85
|
+
bec_widgets/widgets/spiral_progress_bar/ring.py,sha256=WlS3L3mSxFQNtc8T_XEPM7IoVeXYnM2SE5ImjvX6kJU,7097
|
86
86
|
bec_widgets/widgets/spiral_progress_bar/spiral_progress_bar.py,sha256=AjQsZDEqPlTn0kE4xkYKOj2ae5vJ9gW-k3yz1Y32vsY,22543
|
87
87
|
bec_widgets/widgets/toolbar/__init__.py,sha256=d-TP4_cr_VbpwreMM4ePnfZ5YXsEPQ45ibEf75nuGoE,36
|
88
88
|
bec_widgets/widgets/toolbar/toolbar.py,sha256=e0zCD_0q7K4NVhrzD8001Qvfxt-VhqHTgofchS9NgCM,5125
|
@@ -112,26 +112,26 @@ docs/user/getting_started/command_line_introduction.md,sha256=qTGXnxyRajxv7AXbZa
|
|
112
112
|
docs/user/getting_started/getting_started.md,sha256=zYzoHC8xvHF5wDK66thkdamf8mKKNEudiA-fCOzbedM,358
|
113
113
|
docs/user/getting_started/gui_complex_gui.gif,sha256=ovv9u371BGG5GqhzyBMl4mvqMHLfJS0ylr-dR0Ydwtw,6550393
|
114
114
|
docs/user/getting_started/installation.md,sha256=nBl2Hfvo6ua3-tVZn1B-UG0hCTlrFY6_ibXHWnXeegs,1135
|
115
|
-
docs/user/widgets/bec_figure.md,sha256=
|
115
|
+
docs/user/widgets/bec_figure.md,sha256=Ph8ajmESk71Y9nBJsLKLiN-YvGJwN4FdN_Rs3jcObwE,5068
|
116
116
|
docs/user/widgets/image_plot.gif,sha256=_mVFhMTXGqwDOcEtrBHMZj5Thn2sLhDAHEeL2XyHN-s,14098977
|
117
117
|
docs/user/widgets/motor.gif,sha256=FtaWdRHx4UZaGJPpq8LNhMMgX4PFcAB6IZ93JCMEh_w,2280719
|
118
118
|
docs/user/widgets/progress_bar.gif,sha256=5jh0Zw2BBGPuNxszV1DBLJCb4_6glIRX-U2ABjnsK2k,5263592
|
119
119
|
docs/user/widgets/scatter_2D.gif,sha256=yHpsuAUseMafJjI_J5BcOhmE3nu9VFn_Xm9XHzJaH5I,13188862
|
120
|
-
docs/user/widgets/spiral_progress_bar.md,sha256=
|
120
|
+
docs/user/widgets/spiral_progress_bar.md,sha256=fnkg1cRM9y49MwYVXDukHGu80SXHxsI9mU9ZfDkENPs,1114
|
121
121
|
docs/user/widgets/w1D.gif,sha256=tuHbleJpl6bJFNNC2OdndF5LF7IyfvlkFCMGZajrQPs,622773
|
122
122
|
docs/user/widgets/widgets.md,sha256=NFdqTlLTHXueErLzvw4wHwTUrzRSEuRelb1fiT4PySg,352
|
123
123
|
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
124
124
|
tests/end-2-end/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
125
|
-
tests/end-2-end/conftest.py,sha256=
|
126
|
-
tests/end-2-end/test_bec_dock_rpc_e2e.py,sha256=
|
127
|
-
tests/end-2-end/test_bec_figure_rpc_e2e.py,sha256=
|
128
|
-
tests/end-2-end/test_rpc_register_e2e.py,sha256=
|
125
|
+
tests/end-2-end/conftest.py,sha256=taLqiYVzOhJjMre5ypgQjB7wzSXP4soKANW3XfAjems,1773
|
126
|
+
tests/end-2-end/test_bec_dock_rpc_e2e.py,sha256=G-YBfOhJCyV6g74mxXuhAPA9E_BPQ6EUT6xS278aq34,8865
|
127
|
+
tests/end-2-end/test_bec_figure_rpc_e2e.py,sha256=yIbGoDJRN22XVmNASCSh51MdcCMSan1d1qNW1QIXiVk,5082
|
128
|
+
tests/end-2-end/test_rpc_register_e2e.py,sha256=yUt0-UzWZX1keyHO-dyK0zIevtTgBWLP47_zpcvBywI,1583
|
129
129
|
tests/unit_tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
130
130
|
tests/unit_tests/client_mocks.py,sha256=ErrklY7446jXE2_XGKebs_a-2Pqif5ECOPvxVAKRZXY,4170
|
131
131
|
tests/unit_tests/conftest.py,sha256=KrnktXPWmZhnKNue-xGWOLD1XGEvdz9Vf7V2eO3XQ3A,596
|
132
132
|
tests/unit_tests/test_bec_connector.py,sha256=f2XXGGw3NoZLIUrDuZuEWwF_ttOYmmquCgUrV5XkIOY,1951
|
133
133
|
tests/unit_tests/test_bec_dispatcher.py,sha256=rYPiRizHaswhGZw55IBMneDFxmPiCCLAZQBqjEkpdyY,3992
|
134
|
-
tests/unit_tests/test_bec_dock.py,sha256=
|
134
|
+
tests/unit_tests/test_bec_dock.py,sha256=x1mgeNvgu9yVuZvgUkfD60F7FLANGQsXSBhF3n8kyIM,3606
|
135
135
|
tests/unit_tests/test_bec_figure.py,sha256=xYAftY8bI_EH-SlNPD0Tjd7FS_47ouZ1E4hrpjPt7O4,8002
|
136
136
|
tests/unit_tests/test_bec_motor_map.py,sha256=AfD_9-x6VV3TPnkQgNfFYRndPHDsGx-a_YknFeDr6hc,4588
|
137
137
|
tests/unit_tests/test_client_utils.py,sha256=eViJ1Tz-HX9TkMvQH6W8cO-c3_1I8bUc4_Yen6LOc0E,830
|
@@ -150,7 +150,7 @@ tests/unit_tests/test_configs/config_device_no_entry.yaml,sha256=hdvue9KLc_kfNzG
|
|
150
150
|
tests/unit_tests/test_configs/config_scan.yaml,sha256=vo484BbWOjA_e-h6bTjSV9k7QaQHrlAvx-z8wtY-P4E,1915
|
151
151
|
tests/unit_tests/test_msgs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
152
152
|
tests/unit_tests/test_msgs/available_scans_message.py,sha256=m_z97hIrjHXXMa2Ex-UvsPmTxOYXfjxyJaGkIY6StTY,46532
|
153
|
-
bec_widgets-0.57.
|
154
|
-
bec_widgets-0.57.
|
155
|
-
bec_widgets-0.57.
|
156
|
-
bec_widgets-0.57.
|
153
|
+
bec_widgets-0.57.2.dist-info/METADATA,sha256=VKjVy_MzeMyq50c2kmwfQ9hoe6abecAZIR6nSJcwVck,1178
|
154
|
+
bec_widgets-0.57.2.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
|
155
|
+
bec_widgets-0.57.2.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
|
156
|
+
bec_widgets-0.57.2.dist-info/RECORD,,
|
docs/user/widgets/bec_figure.md
CHANGED
@@ -20,7 +20,7 @@ In the following, we describe 4 different type of widgets thaat are available in
|
|
20
20
|
The following code snipped demonstrates how to create a 1D waveform plot using BEC Widgets within BEC. More details about BEC Widgets in BEC can be found in the getting started section within the [introduction to the command line.](user.command_line_introduction)
|
21
21
|
```python
|
22
22
|
# adds a new dock, a new BECFigure and a BECWaveForm to the dock
|
23
|
-
plt = gui.add_dock().
|
23
|
+
plt = gui.add_dock().add_widget('BECFigure').plot('samx', 'bpm4i')
|
24
24
|
# add a second curve to the same plot
|
25
25
|
plt.add_curve_scan('samx', 'bpm3i')
|
26
26
|
plt.set_title("Gauss plots vs. samx")
|
@@ -53,7 +53,7 @@ dev.bpm3i.sim.select_sim_model("StepModel")
|
|
53
53
|
The following code snipped demonstrates how to create a 2D scatter plot using BEC Widgets within BEC.
|
54
54
|
```python
|
55
55
|
# adds a new dock, a new BECFigure and a BECWaveForm to the dock
|
56
|
-
plt = gui.add_dock().
|
56
|
+
plt = gui.add_dock().add_widget('BECFigure').add_plot('samx', 'samy', 'bpm4i')
|
57
57
|
```
|
58
58
|
|
59
59
|
(user.widgets.motor_map)=
|
@@ -72,7 +72,7 @@ plt = gui.add_dock().add_widget_bec('BECFigure').add_plot('samx', 'samy', 'bpm4i
|
|
72
72
|
The following code snipped demonstrates how to create a motor map using BEC Widgets within BEC.
|
73
73
|
```python
|
74
74
|
# add a motor map to the gui
|
75
|
-
mot_map = gui.add_dock().
|
75
|
+
mot_map = gui.add_dock().add_widget('BECFigure').motor_map('samx', 'samy')
|
76
76
|
# change the number of points displayed
|
77
77
|
```
|
78
78
|
|
@@ -91,7 +91,7 @@ mot_map = gui.add_dock().add_widget_bec('BECFigure').motor_map('samx', 'samy')
|
|
91
91
|
The following code snipped demonstrates how to create a motor map using BEC Widgets within BEC.
|
92
92
|
```python
|
93
93
|
# add a camera view for the eiger camera to the gui
|
94
|
-
cam_widget = gui.add_dock().
|
94
|
+
cam_widget = gui.add_dock().add_widget('BECFigure').image('eiger')
|
95
95
|
# set the title of the camera view
|
96
96
|
cam_widget.set_title("Camera Image Eiger")
|
97
97
|
# change the color map range, e.g. from 0 to 100, per default it is autoscaling
|
@@ -15,7 +15,7 @@
|
|
15
15
|
The following code snipped demonstrates how to create a 2D scatter plot using BEC Widgets within BEC.
|
16
16
|
```python
|
17
17
|
# adds a new dock with a spiral progress bar
|
18
|
-
progress = gui.add_dock().
|
18
|
+
progress = gui.add_dock().add_widget("SpiralProgressBar")
|
19
19
|
# customize the size of the ring
|
20
|
-
progress.
|
20
|
+
progress.set_line_width(20)
|
21
21
|
```
|
pyproject.toml
CHANGED
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "bec_widgets"
|
7
|
-
version = "0.57.
|
7
|
+
version = "0.57.2"
|
8
8
|
description = "BEC Widgets"
|
9
9
|
requires-python = ">=3.10"
|
10
10
|
classifiers = [
|
@@ -31,6 +31,7 @@ dev = [
|
|
31
31
|
"pytest",
|
32
32
|
"pytest-random-order",
|
33
33
|
"pytest-timeout",
|
34
|
+
"pytest-xvfb",
|
34
35
|
"coverage",
|
35
36
|
"pytest-qt",
|
36
37
|
"isort",
|
tests/end-2-end/conftest.py
CHANGED
@@ -1,40 +1,55 @@
|
|
1
|
+
import random
|
2
|
+
import time
|
3
|
+
from contextlib import contextmanager
|
4
|
+
|
1
5
|
import pytest
|
6
|
+
from bec_lib.endpoints import MessageEndpoints
|
2
7
|
|
8
|
+
from bec_widgets.cli.client_utils import _start_plot_process
|
3
9
|
from bec_widgets.cli.rpc_register import RPCRegister
|
4
|
-
from bec_widgets.cli.server import BECWidgetsCLIServer
|
5
10
|
from bec_widgets.utils import BECDispatcher
|
6
11
|
from bec_widgets.widgets import BECDockArea, BECFigure
|
7
12
|
|
8
13
|
|
14
|
+
# make threads check in autouse, **will be executed at the end**; better than
|
15
|
+
# having it in fixtures for each test, since it prevents from needing to
|
16
|
+
# 'manually' shutdown bec_client_lib (for example) to make it happy, whereas
|
17
|
+
# whereas in fact bec_client_lib makes its on cleanup
|
9
18
|
@pytest.fixture(autouse=True)
|
10
|
-
def
|
11
|
-
|
12
|
-
|
19
|
+
def threads_check_fixture(threads_check):
|
20
|
+
return
|
21
|
+
|
22
|
+
|
23
|
+
@pytest.fixture
|
24
|
+
def gui_id():
|
25
|
+
return f"figure_{random.randint(0,100)}" # make a new gui id each time, to ensure no 'gui is alive' zombie key can perturbate
|
26
|
+
|
27
|
+
|
28
|
+
@contextmanager
|
29
|
+
def plot_server(gui_id, klass, client_lib):
|
30
|
+
dispatcher = BECDispatcher(client=client_lib) # Has to init singleton with fixture client
|
31
|
+
process, output_thread = _start_plot_process(
|
32
|
+
gui_id, klass, client_lib._client._service_config.redis
|
33
|
+
)
|
34
|
+
try:
|
35
|
+
while client_lib._client.connector.get(MessageEndpoints.gui_heartbeat(gui_id)) is None:
|
36
|
+
time.sleep(0.3)
|
37
|
+
yield gui_id
|
38
|
+
finally:
|
39
|
+
process.terminate()
|
40
|
+
process.wait()
|
41
|
+
output_thread.join()
|
42
|
+
dispatcher.disconnect_all()
|
43
|
+
dispatcher.reset_singleton()
|
13
44
|
|
14
45
|
|
15
46
|
@pytest.fixture
|
16
|
-
def rpc_server_figure(
|
17
|
-
|
18
|
-
|
19
|
-
qtbot.addWidget(server.gui)
|
20
|
-
qtbot.waitExposed(server.gui)
|
21
|
-
qtbot.wait(1000) # 1s long to wait until gui is ready
|
22
|
-
yield server
|
23
|
-
dispatcher.disconnect_all()
|
24
|
-
server.client.shutdown()
|
25
|
-
server.shutdown()
|
26
|
-
dispatcher.reset_singleton()
|
47
|
+
def rpc_server_figure(gui_id, bec_client_lib):
|
48
|
+
with plot_server(gui_id, BECFigure, bec_client_lib) as server:
|
49
|
+
yield server
|
27
50
|
|
28
51
|
|
29
52
|
@pytest.fixture
|
30
|
-
def rpc_server_dock(
|
31
|
-
|
32
|
-
|
33
|
-
qtbot.addWidget(server.gui)
|
34
|
-
qtbot.waitExposed(server.gui)
|
35
|
-
qtbot.wait(1000) # 1s long to wait until gui is ready
|
36
|
-
yield server
|
37
|
-
dispatcher.disconnect_all()
|
38
|
-
server.client.shutdown()
|
39
|
-
server.shutdown()
|
40
|
-
dispatcher.reset_singleton()
|
53
|
+
def rpc_server_dock(gui_id, bec_client_lib):
|
54
|
+
with plot_server(gui_id, BECDockArea, bec_client_lib) as server:
|
55
|
+
yield server
|
@@ -1,3 +1,5 @@
|
|
1
|
+
import time
|
2
|
+
|
1
3
|
import numpy as np
|
2
4
|
import pytest
|
3
5
|
from bec_lib.client import BECClient
|
@@ -8,24 +10,10 @@ from bec_widgets.cli.client import BECDockArea, BECFigure, BECImageShow, BECMoto
|
|
8
10
|
from bec_widgets.utils import Colors
|
9
11
|
|
10
12
|
|
11
|
-
|
12
|
-
def cli_bec_client(rpc_server_dock):
|
13
|
-
"""
|
14
|
-
Fixture to create a BECClient instance that is independent of the GUI.
|
15
|
-
"""
|
16
|
-
# pylint: disable=protected-access
|
17
|
-
cli_client = BECClient(forced=True, config=rpc_server_dock.client._service_config)
|
18
|
-
cli_client.start()
|
19
|
-
yield cli_client
|
20
|
-
cli_client.shutdown()
|
21
|
-
|
22
|
-
|
23
|
-
def test_rpc_add_dock_with_figure_e2e(rpc_server_dock, qtbot):
|
24
|
-
dock = BECDockArea(rpc_server_dock.gui_id)
|
25
|
-
dock_server = rpc_server_dock.gui
|
26
|
-
|
13
|
+
def test_rpc_add_dock_with_figure_e2e(bec_client_lib, rpc_server_dock):
|
27
14
|
# BEC client shortcuts
|
28
|
-
|
15
|
+
dock = BECDockArea(rpc_server_dock)
|
16
|
+
client = bec_client_lib
|
29
17
|
dev = client.device_manager.devices
|
30
18
|
scans = client.scans
|
31
19
|
queue = client.queue
|
@@ -35,17 +23,18 @@ def test_rpc_add_dock_with_figure_e2e(rpc_server_dock, qtbot):
|
|
35
23
|
d1 = dock.add_dock("dock_1")
|
36
24
|
d2 = dock.add_dock("dock_2")
|
37
25
|
|
38
|
-
|
39
|
-
|
26
|
+
dock_config = dock.config_dict
|
27
|
+
assert len(dock_config["docks"]) == 3
|
40
28
|
# Add 3 figures with some widgets
|
41
|
-
fig0 = d0.
|
42
|
-
fig1 = d1.
|
43
|
-
fig2 = d2.
|
29
|
+
fig0 = d0.add_widget("BECFigure")
|
30
|
+
fig1 = d1.add_widget("BECFigure")
|
31
|
+
fig2 = d2.add_widget("BECFigure")
|
44
32
|
|
45
|
-
|
46
|
-
assert len(
|
47
|
-
assert len(
|
48
|
-
assert len(
|
33
|
+
dock_config = dock.config_dict
|
34
|
+
assert len(dock_config["docks"]) == 3
|
35
|
+
assert len(dock_config["docks"]["dock_0"]["widgets"]) == 1
|
36
|
+
assert len(dock_config["docks"]["dock_1"]["widgets"]) == 1
|
37
|
+
assert len(dock_config["docks"]["dock_2"]["widgets"]) == 1
|
49
38
|
|
50
39
|
assert fig1.__class__.__name__ == "BECFigure"
|
51
40
|
assert fig1.__class__ == BECFigure
|
@@ -98,7 +87,7 @@ def test_rpc_add_dock_with_figure_e2e(rpc_server_dock, qtbot):
|
|
98
87
|
|
99
88
|
# wait for scan to finish
|
100
89
|
while not status.status == "COMPLETED":
|
101
|
-
|
90
|
+
time.sleep(0.2)
|
102
91
|
|
103
92
|
# plot
|
104
93
|
plt_last_scan_data = queue.scan_storage.storage[-1].data
|
@@ -110,7 +99,7 @@ def test_rpc_add_dock_with_figure_e2e(rpc_server_dock, qtbot):
|
|
110
99
|
last_image_device = client.connector.get_last(MessageEndpoints.device_monitor("eiger"))[
|
111
100
|
"data"
|
112
101
|
].data
|
113
|
-
|
102
|
+
time.sleep(0.5)
|
114
103
|
last_image_plot = im.images[0].get_data()
|
115
104
|
np.testing.assert_equal(last_image_device, last_image_plot)
|
116
105
|
|
@@ -129,93 +118,91 @@ def test_rpc_add_dock_with_figure_e2e(rpc_server_dock, qtbot):
|
|
129
118
|
)
|
130
119
|
|
131
120
|
|
132
|
-
def test_dock_manipulations_e2e(rpc_server_dock
|
133
|
-
dock = BECDockArea(rpc_server_dock
|
134
|
-
dock_server = rpc_server_dock.gui
|
121
|
+
def test_dock_manipulations_e2e(rpc_server_dock):
|
122
|
+
dock = BECDockArea(rpc_server_dock)
|
135
123
|
|
136
124
|
d0 = dock.add_dock("dock_0")
|
137
125
|
d1 = dock.add_dock("dock_1")
|
138
126
|
d2 = dock.add_dock("dock_2")
|
139
|
-
|
127
|
+
dock_config = dock.config_dict
|
128
|
+
assert len(dock_config["docks"]) == 3
|
140
129
|
|
141
130
|
d0.detach()
|
142
131
|
dock.detach_dock("dock_2")
|
143
|
-
|
144
|
-
assert len(
|
132
|
+
dock_config = dock.config_dict
|
133
|
+
assert len(dock_config["docks"]) == 3
|
134
|
+
assert len(dock.temp_areas) == 2
|
145
135
|
|
146
136
|
d0.attach()
|
147
|
-
|
148
|
-
assert len(
|
137
|
+
dock_config = dock.config_dict
|
138
|
+
assert len(dock_config["docks"]) == 3
|
139
|
+
assert len(dock.temp_areas) == 1
|
149
140
|
|
150
141
|
d2.remove()
|
151
|
-
|
142
|
+
dock_config = dock.config_dict
|
143
|
+
assert len(dock_config["docks"]) == 2
|
152
144
|
|
153
|
-
assert
|
154
|
-
docks_list = list(dict(dock_server.docks).keys())
|
155
|
-
assert ["dock_0", "dock_1"] == docks_list
|
145
|
+
assert ["dock_0", "dock_1"] == list(dock_config["docks"])
|
156
146
|
|
157
147
|
dock.clear_all()
|
158
148
|
|
159
|
-
|
160
|
-
assert len(
|
149
|
+
dock_config = dock.config_dict
|
150
|
+
assert len(dock_config["docks"]) == 0
|
151
|
+
assert len(dock.temp_areas) == 0
|
161
152
|
|
162
153
|
|
163
154
|
def test_spiral_bar(rpc_server_dock):
|
164
|
-
dock = BECDockArea(rpc_server_dock
|
165
|
-
dock_server = rpc_server_dock.gui
|
155
|
+
dock = BECDockArea(rpc_server_dock)
|
166
156
|
|
167
157
|
d0 = dock.add_dock(name="dock_0")
|
168
158
|
|
169
|
-
bar = d0.
|
159
|
+
bar = d0.add_widget("SpiralProgressBar")
|
170
160
|
assert bar.__class__.__name__ == "SpiralProgressBar"
|
171
161
|
|
172
162
|
bar.set_number_of_bars(5)
|
173
163
|
bar.set_colors_from_map("viridis")
|
174
164
|
bar.set_value([10, 20, 30, 40, 50])
|
175
165
|
|
176
|
-
|
166
|
+
bar_config = bar.config_dict
|
177
167
|
|
178
|
-
expected_colors = Colors.golden_angle_color("viridis", 5, "RGB")
|
179
|
-
bar_colors = [ring.color
|
180
|
-
bar_values = [ring.
|
168
|
+
expected_colors = [list(color) for color in Colors.golden_angle_color("viridis", 5, "RGB")]
|
169
|
+
bar_colors = [ring.config_dict["color"] for ring in bar.rings]
|
170
|
+
bar_values = [ring.config_dict["value"] for ring in bar.rings]
|
171
|
+
assert bar_config["num_bars"] == 5
|
181
172
|
assert bar_values == [10, 20, 30, 40, 50]
|
182
173
|
assert bar_colors == expected_colors
|
183
174
|
|
184
175
|
|
185
|
-
def test_spiral_bar_scan_update(
|
186
|
-
dock = BECDockArea(rpc_server_dock
|
187
|
-
dock_server = rpc_server_dock.gui
|
176
|
+
def test_spiral_bar_scan_update(bec_client_lib, rpc_server_dock):
|
177
|
+
dock = BECDockArea(rpc_server_dock)
|
188
178
|
|
189
179
|
d0 = dock.add_dock("dock_0")
|
190
180
|
|
191
|
-
d0.
|
181
|
+
bar = d0.add_widget("SpiralProgressBar")
|
192
182
|
|
193
|
-
client =
|
183
|
+
client = bec_client_lib
|
194
184
|
dev = client.device_manager.devices
|
185
|
+
dev.samx.tolerance.set(0)
|
186
|
+
dev.samy.tolerance.set(0)
|
195
187
|
scans = client.scans
|
196
188
|
|
197
189
|
status = scans.line_scan(dev.samx, -5, 5, steps=10, exp_time=0.05, relative=False)
|
190
|
+
status.wait()
|
198
191
|
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
assert bar_server.config.num_bars == 1
|
205
|
-
np.testing.assert_allclose(bar_server.rings[0].config.value, 10, atol=0.1)
|
206
|
-
np.testing.assert_allclose(bar_server.rings[0].config.min_value, 0, atol=0.1)
|
207
|
-
np.testing.assert_allclose(bar_server.rings[0].config.max_value, 10, atol=0.1)
|
192
|
+
bar_config = bar.config_dict
|
193
|
+
assert bar_config["num_bars"] == 1
|
194
|
+
assert bar_config["rings"][0]["value"] == 10
|
195
|
+
assert bar_config["rings"][0]["min_value"] == 0
|
196
|
+
assert bar_config["rings"][0]["max_value"] == 10
|
208
197
|
|
209
198
|
status = scans.grid_scan(dev.samx, -5, 5, 4, dev.samy, -10, 10, 4, relative=True, exp_time=0.1)
|
199
|
+
status.wait()
|
210
200
|
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
assert
|
216
|
-
np.testing.assert_allclose(bar_server.rings[0].config.value, 16, atol=0.1)
|
217
|
-
np.testing.assert_allclose(bar_server.rings[0].config.min_value, 0, atol=0.1)
|
218
|
-
np.testing.assert_allclose(bar_server.rings[0].config.max_value, 16, atol=0.1)
|
201
|
+
bar_config = bar.config_dict
|
202
|
+
assert bar_config["num_bars"] == 1
|
203
|
+
assert bar_config["rings"][0]["value"] == 16
|
204
|
+
assert bar_config["rings"][0]["min_value"] == 0
|
205
|
+
assert bar_config["rings"][0]["max_value"] == 16
|
219
206
|
|
220
207
|
init_samx = dev.samx.read()["samx"]["value"]
|
221
208
|
init_samy = dev.samy.read()["samy"]["value"]
|
@@ -226,23 +213,20 @@ def test_spiral_bar_scan_update(rpc_server_dock, qtbot):
|
|
226
213
|
dev.samy.velocity.put(5)
|
227
214
|
|
228
215
|
status = scans.umv(dev.samx, 5, dev.samy, 10, relative=True)
|
216
|
+
status.wait()
|
229
217
|
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
assert
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
np.testing.assert_allclose(bar_server.rings[1].config.min_value, init_samy, atol=0.1)
|
239
|
-
np.testing.assert_allclose(bar_server.rings[0].config.max_value, final_samx, atol=0.1)
|
240
|
-
np.testing.assert_allclose(bar_server.rings[1].config.max_value, final_samy, atol=0.1)
|
218
|
+
bar_config = bar.config_dict
|
219
|
+
assert bar_config["num_bars"] == 2
|
220
|
+
assert bar_config["rings"][0]["value"] == final_samx
|
221
|
+
assert bar_config["rings"][1]["value"] == final_samy
|
222
|
+
assert bar_config["rings"][0]["min_value"] == init_samx
|
223
|
+
assert bar_config["rings"][0]["max_value"] == final_samx
|
224
|
+
assert bar_config["rings"][1]["min_value"] == init_samy
|
225
|
+
assert bar_config["rings"][1]["max_value"] == final_samy
|
241
226
|
|
242
227
|
|
243
|
-
def test_auto_update(
|
244
|
-
dock = BECDockArea(rpc_server_dock
|
245
|
-
dock._client = bec_client
|
228
|
+
def test_auto_update(bec_client_lib, rpc_server_dock):
|
229
|
+
dock = BECDockArea(rpc_server_dock)
|
246
230
|
|
247
231
|
AutoUpdates.enabled = True
|
248
232
|
AutoUpdates.create_default_dock = True
|
@@ -253,16 +237,13 @@ def test_auto_update(rpc_server_dock, bec_client, qtbot):
|
|
253
237
|
# we need to start the update script manually; normally this is done when the GUI is started
|
254
238
|
dock._start_update_script()
|
255
239
|
|
256
|
-
client =
|
240
|
+
client = bec_client_lib
|
257
241
|
dev = client.device_manager.devices
|
258
242
|
scans = client.scans
|
259
243
|
queue = client.queue
|
260
244
|
|
261
245
|
status = scans.line_scan(dev.samx, -5, 5, steps=10, exp_time=0.05, relative=False)
|
262
|
-
|
263
|
-
# wait for scan to finish
|
264
|
-
while not status.status == "COMPLETED":
|
265
|
-
qtbot.wait(200)
|
246
|
+
status.wait()
|
266
247
|
|
267
248
|
last_scan_data = queue.scan_storage.storage[-1].data
|
268
249
|
|
@@ -278,10 +259,7 @@ def test_auto_update(rpc_server_dock, bec_client, qtbot):
|
|
278
259
|
status = scans.grid_scan(
|
279
260
|
dev.samx, -10, 10, 5, dev.samy, -5, 5, 5, exp_time=0.05, relative=False
|
280
261
|
)
|
281
|
-
|
282
|
-
# wait for scan to finish
|
283
|
-
while not status.status == "COMPLETED":
|
284
|
-
qtbot.wait(200)
|
262
|
+
status.wait()
|
285
263
|
|
286
264
|
plt = dock.auto_updates.get_default_figure()
|
287
265
|
widgets = plt.widget_list
|
@@ -5,9 +5,8 @@ from bec_lib.endpoints import MessageEndpoints
|
|
5
5
|
from bec_widgets.cli.client import BECFigure, BECImageShow, BECMotorMap, BECWaveform
|
6
6
|
|
7
7
|
|
8
|
-
def test_rpc_waveform1d_custom_curve(rpc_server_figure
|
9
|
-
fig = BECFigure(rpc_server_figure
|
10
|
-
fig_server = rpc_server_figure.gui
|
8
|
+
def test_rpc_waveform1d_custom_curve(rpc_server_figure):
|
9
|
+
fig = BECFigure(rpc_server_figure)
|
11
10
|
|
12
11
|
ax = fig.add_plot()
|
13
12
|
curve = ax.add_curve_custom([1, 2, 3], [1, 2, 3])
|
@@ -15,13 +14,12 @@ def test_rpc_waveform1d_custom_curve(rpc_server_figure, qtbot):
|
|
15
14
|
curve = ax.curves[0]
|
16
15
|
curve.set_color("blue")
|
17
16
|
|
18
|
-
assert len(
|
19
|
-
assert len(
|
17
|
+
assert len(fig.widgets) == 1
|
18
|
+
assert len(fig.widgets[ax.rpc_id].curves) == 1
|
20
19
|
|
21
20
|
|
22
21
|
def test_rpc_plotting_shortcuts_init_configs(rpc_server_figure, qtbot):
|
23
|
-
fig = BECFigure(rpc_server_figure
|
24
|
-
fig_server = rpc_server_figure.gui
|
22
|
+
fig = BECFigure(rpc_server_figure)
|
25
23
|
|
26
24
|
plt = fig.plot(x_name="samx", y_name="bpm4i")
|
27
25
|
im = fig.image("eiger")
|
@@ -29,7 +27,7 @@ def test_rpc_plotting_shortcuts_init_configs(rpc_server_figure, qtbot):
|
|
29
27
|
plt_z = fig.add_plot("samx", "samy", "bpm4i")
|
30
28
|
|
31
29
|
# Checking if classes are correctly initialised
|
32
|
-
assert len(
|
30
|
+
assert len(fig.widgets) == 4
|
33
31
|
assert plt.__class__.__name__ == "BECWaveform"
|
34
32
|
assert plt.__class__ == BECWaveform
|
35
33
|
assert im.__class__.__name__ == "BECImageShow"
|
@@ -75,24 +73,21 @@ def test_rpc_plotting_shortcuts_init_configs(rpc_server_figure, qtbot):
|
|
75
73
|
}
|
76
74
|
|
77
75
|
|
78
|
-
def test_rpc_waveform_scan(rpc_server_figure,
|
79
|
-
fig = BECFigure(rpc_server_figure
|
76
|
+
def test_rpc_waveform_scan(rpc_server_figure, bec_client_lib):
|
77
|
+
fig = BECFigure(rpc_server_figure)
|
80
78
|
|
81
79
|
# add 3 different curves to track
|
82
80
|
plt = fig.plot(x_name="samx", y_name="bpm4i")
|
83
81
|
fig.plot(x_name="samx", y_name="bpm3a")
|
84
82
|
fig.plot(x_name="samx", y_name="bpm4d")
|
85
83
|
|
86
|
-
client =
|
84
|
+
client = bec_client_lib
|
87
85
|
dev = client.device_manager.devices
|
88
86
|
scans = client.scans
|
89
87
|
queue = client.queue
|
90
88
|
|
91
89
|
status = scans.line_scan(dev.samx, -5, 5, steps=10, exp_time=0.05, relative=False)
|
92
|
-
|
93
|
-
# wait for scan to finish
|
94
|
-
while not status.status == "COMPLETED":
|
95
|
-
qtbot.wait(200)
|
90
|
+
status.wait()
|
96
91
|
|
97
92
|
last_scan_data = queue.scan_storage.storage[-1].data
|
98
93
|
|
@@ -108,38 +103,33 @@ def test_rpc_waveform_scan(rpc_server_figure, qtbot):
|
|
108
103
|
assert plt_data["bpm4d-bpm4d"]["y"] == last_scan_data["bpm4d"]["bpm4d"].val
|
109
104
|
|
110
105
|
|
111
|
-
def test_rpc_image(rpc_server_figure,
|
112
|
-
fig = BECFigure(rpc_server_figure
|
106
|
+
def test_rpc_image(rpc_server_figure, bec_client_lib):
|
107
|
+
fig = BECFigure(rpc_server_figure)
|
113
108
|
|
114
109
|
im = fig.image("eiger")
|
115
110
|
|
116
|
-
client =
|
111
|
+
client = bec_client_lib
|
117
112
|
dev = client.device_manager.devices
|
118
113
|
scans = client.scans
|
119
114
|
|
120
115
|
status = scans.line_scan(dev.samx, -5, 5, steps=10, exp_time=0.05, relative=False)
|
121
|
-
|
122
|
-
# wait for scan to finish
|
123
|
-
while not status.status == "COMPLETED":
|
124
|
-
qtbot.wait(200)
|
116
|
+
status.wait()
|
125
117
|
|
126
118
|
last_image_device = client.connector.get_last(MessageEndpoints.device_monitor("eiger"))[
|
127
119
|
"data"
|
128
120
|
].data
|
129
|
-
qtbot.wait(500)
|
130
121
|
last_image_plot = im.images[0].get_data()
|
131
122
|
|
132
123
|
# check plotted data
|
133
124
|
np.testing.assert_equal(last_image_device, last_image_plot)
|
134
125
|
|
135
126
|
|
136
|
-
def test_rpc_motor_map(rpc_server_figure,
|
137
|
-
fig = BECFigure(rpc_server_figure
|
138
|
-
fig_server = rpc_server_figure.gui
|
127
|
+
def test_rpc_motor_map(rpc_server_figure, bec_client_lib):
|
128
|
+
fig = BECFigure(rpc_server_figure)
|
139
129
|
|
140
130
|
motor_map = fig.motor_map("samx", "samy")
|
141
131
|
|
142
|
-
client =
|
132
|
+
client = bec_client_lib
|
143
133
|
dev = client.device_manager.devices
|
144
134
|
scans = client.scans
|
145
135
|
|
@@ -147,10 +137,8 @@ def test_rpc_motor_map(rpc_server_figure, qtbot):
|
|
147
137
|
initial_pos_y = dev.samy.read()["samy"]["value"]
|
148
138
|
|
149
139
|
status = scans.mv(dev.samx, 1, dev.samy, 2, relative=True)
|
140
|
+
status.wait()
|
150
141
|
|
151
|
-
# wait for scan to finish
|
152
|
-
while not status.status == "COMPLETED":
|
153
|
-
qtbot.wait(200)
|
154
142
|
final_pos_x = dev.samx.read()["samx"]["value"]
|
155
143
|
final_pos_y = dev.samy.read()["samy"]["value"]
|
156
144
|
|
@@ -3,40 +3,30 @@ import pytest
|
|
3
3
|
from bec_widgets.cli.client import BECFigure, BECImageShow, BECMotorMap, BECWaveform
|
4
4
|
|
5
5
|
|
6
|
-
def
|
7
|
-
|
8
|
-
Recursively find the deepest value in a dictionary
|
9
|
-
Args:
|
10
|
-
d(dict): Dictionary to search
|
11
|
-
|
12
|
-
Returns:
|
13
|
-
The deepest value in the dictionary.
|
14
|
-
"""
|
15
|
-
if isinstance(d, dict):
|
16
|
-
if d:
|
17
|
-
return find_deepest_value(next(iter(d.values())))
|
18
|
-
return d
|
19
|
-
|
20
|
-
|
21
|
-
def test_rpc_register_list_connections(rpc_server_figure, rpc_register, qtbot):
|
22
|
-
fig = BECFigure(rpc_server_figure.gui_id)
|
23
|
-
fig_server = rpc_server_figure.gui
|
6
|
+
def test_rpc_register_list_connections(rpc_server_figure):
|
7
|
+
fig = BECFigure(rpc_server_figure)
|
24
8
|
|
25
9
|
plt = fig.plot(x_name="samx", y_name="bpm4i")
|
26
10
|
im = fig.image("eiger")
|
27
11
|
motor_map = fig.motor_map("samx", "samy")
|
28
12
|
plt_z = fig.add_plot("samx", "samy", "bpm4i")
|
29
13
|
|
30
|
-
|
14
|
+
# keep only class names from objects, since objects on server and client are different
|
15
|
+
# so the best we can do is to compare types (rpc register is unit-tested elsewhere)
|
16
|
+
all_connections = {obj_id: type(obj).__name__ for obj_id, obj in fig.get_all_rpc().items()}
|
31
17
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
18
|
+
all_subwidgets_expected = {wid: type(widget).__name__ for wid, widget in fig.widgets.items()}
|
19
|
+
curve_1D = fig.widgets[plt.rpc_id]
|
20
|
+
curve_2D = fig.widgets[plt_z.rpc_id]
|
21
|
+
curves_expected = {
|
22
|
+
curve_1D.rpc_id: type(curve_1D).__name__,
|
23
|
+
curve_2D.rpc_id: type(curve_2D).__name__,
|
24
|
+
}
|
25
|
+
curves_expected.update({curve._gui_id: type(curve).__name__ for curve in curve_1D.curves})
|
26
|
+
curves_expected.update({curve._gui_id: type(curve).__name__ for curve in curve_2D.curves})
|
27
|
+
fig_expected = {fig.rpc_id: type(fig).__name__}
|
38
28
|
image_item_expected = {
|
39
|
-
|
29
|
+
fig.widgets[im.rpc_id].images[0].rpc_id: type(fig.widgets[im.rpc_id].images[0]).__name__
|
40
30
|
}
|
41
31
|
|
42
32
|
all_connections_expected = {
|
@@ -58,7 +58,7 @@ def test_bec_dock_area_add_remove_dock(bec_dock_area, qtbot):
|
|
58
58
|
|
59
59
|
def test_add_remove_bec_figure_to_dock(bec_dock_area):
|
60
60
|
d0 = bec_dock_area.add_dock()
|
61
|
-
fig = d0.
|
61
|
+
fig = d0.add_widget("BECFigure")
|
62
62
|
plt = fig.plot(x_name="samx", y_name="bpm4i")
|
63
63
|
im = fig.image("eiger")
|
64
64
|
mm = fig.motor_map("samx", "samy")
|
File without changes
|
File without changes
|