bec-widgets 0.55.0__py3-none-any.whl → 0.56.1__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 +113 -8
- CHANGELOG.md +34 -28
- PKG-INFO +3 -1
- bec_widgets/examples/jupyter_console/jupyter_console_window.py +28 -38
- bec_widgets/examples/motor_movement/motor_control_compilations.py +1 -7
- bec_widgets/utils/__init__.py +1 -0
- bec_widgets/utils/crosshair.py +13 -9
- bec_widgets/utils/ui_loader.py +58 -0
- bec_widgets/widgets/motor_control/motor_table/motor_table.py +44 -43
- bec_widgets/widgets/motor_control/movement_absolute/movement_absolute.py +25 -23
- bec_widgets/widgets/motor_control/movement_relative/movement_relative.py +51 -48
- bec_widgets/widgets/spiral_progress_bar/ring.py +5 -5
- {bec_widgets-0.55.0.dist-info → bec_widgets-0.56.1.dist-info}/METADATA +3 -1
- {bec_widgets-0.55.0.dist-info → bec_widgets-0.56.1.dist-info}/RECORD +22 -43
- docs/user/apps.md +1 -26
- pyproject.toml +2 -1
- tests/end-2-end/test_bec_dock_rpc_e2e.py +1 -1
- tests/unit_tests/test_client_utils.py +2 -2
- tests/unit_tests/test_crosshair.py +5 -5
- tests/unit_tests/test_motor_control.py +49 -45
- bec_widgets/examples/eiger_plot/__init__.py +0 -0
- bec_widgets/examples/eiger_plot/eiger_plot.py +0 -307
- bec_widgets/examples/eiger_plot/eiger_plot.ui +0 -207
- bec_widgets/examples/mca_readout/__init__.py +0 -0
- bec_widgets/examples/mca_readout/mca_plot.py +0 -159
- bec_widgets/examples/mca_readout/mca_sim.py +0 -28
- bec_widgets/examples/modular_app/___init__.py +0 -0
- bec_widgets/examples/modular_app/modular.ui +0 -92
- bec_widgets/examples/modular_app/modular_app.py +0 -197
- bec_widgets/examples/motor_movement/config_example.yaml +0 -17
- bec_widgets/examples/motor_movement/csax_bec_config.yaml +0 -10
- bec_widgets/examples/motor_movement/csaxs_config.yaml +0 -17
- bec_widgets/examples/motor_movement/motor_example.py +0 -1344
- bec_widgets/examples/stream_plot/__init__.py +0 -0
- bec_widgets/examples/stream_plot/line_plot.ui +0 -155
- bec_widgets/examples/stream_plot/stream_plot.py +0 -337
- docs/user/apps/modular_app.md +0 -6
- docs/user/apps/motor_app.md +0 -34
- docs/user/apps/motor_app_10fps.gif +0 -0
- docs/user/apps/plot_app.md +0 -6
- tests/unit_tests/test_eiger_plot.py +0 -115
- tests/unit_tests/test_stream_plot.py +0 -158
- {bec_widgets-0.55.0.dist-info → bec_widgets-0.56.1.dist-info}/WHEEL +0 -0
- {bec_widgets-0.55.0.dist-info → bec_widgets-0.56.1.dist-info}/licenses/LICENSE +0 -0
.gitlab-ci.yml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# This file is a template, and might need editing before it works on your project.
|
2
2
|
# Official language image. Look for the different tagged releases at:
|
3
3
|
# https://hub.docker.com/r/library/python/tags/
|
4
|
-
image: $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX/python:3.
|
4
|
+
image: $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX/python:3.11
|
5
5
|
#commands to run in the Docker container before starting each job.
|
6
6
|
variables:
|
7
7
|
DOCKER_TLS_CERTDIR: ""
|
@@ -23,7 +23,6 @@ workflow:
|
|
23
23
|
include:
|
24
24
|
- template: Security/Secret-Detection.gitlab-ci.yml
|
25
25
|
|
26
|
-
|
27
26
|
# different stages in the pipeline
|
28
27
|
stages:
|
29
28
|
- Formatter
|
@@ -65,7 +64,7 @@ pylint:
|
|
65
64
|
- ./pylint/
|
66
65
|
expire_in: 1 week
|
67
66
|
rules:
|
68
|
-
- if: $CI_PROJECT_PATH == "bec/bec_widgets"
|
67
|
+
- if: $CI_PROJECT_PATH == "bec/bec_widgets"
|
69
68
|
|
70
69
|
pylint-check:
|
71
70
|
stage: Formatter
|
@@ -98,7 +97,7 @@ pylint-check:
|
|
98
97
|
- ./pylint/
|
99
98
|
expire_in: 1 week
|
100
99
|
rules:
|
101
|
-
- if: $CI_PROJECT_PATH == "bec/bec_widgets"
|
100
|
+
- if: $CI_PROJECT_PATH == "bec/bec_widgets"
|
102
101
|
|
103
102
|
tests:
|
104
103
|
stage: test
|
@@ -124,17 +123,124 @@ tests:
|
|
124
123
|
coverage_format: cobertura
|
125
124
|
path: coverage.xml
|
126
125
|
|
126
|
+
tests-3.10-pyside6:
|
127
|
+
extends: "tests"
|
128
|
+
stage: AdditionalTests
|
129
|
+
image: $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX/python:3.10
|
130
|
+
script:
|
131
|
+
- git clone --branch $BEC_CORE_BRANCH https://gitlab.psi.ch/bec/bec.git
|
132
|
+
- git clone --branch $OPHYD_DEVICES_BRANCH https://gitlab.psi.ch/bec/ophyd_devices.git
|
133
|
+
- export OHPYD_DEVICES_PATH=$PWD/ophyd_devices
|
134
|
+
- apt-get update
|
135
|
+
- apt-get install -y libgl1-mesa-glx libegl1-mesa x11-utils libxkbcommon-x11-0 libdbus-1-3
|
136
|
+
- pip install -e ./bec/bec_lib[dev]
|
137
|
+
- pip install -e .[dev,pyside6]
|
138
|
+
- pytest -v --junitxml=report.xml --random-order ./tests/unit_tests
|
139
|
+
allow_failure: true
|
127
140
|
|
128
|
-
tests-3.
|
141
|
+
tests-3.12-pyside6:
|
142
|
+
extends: "tests"
|
143
|
+
stage: AdditionalTests
|
144
|
+
image: $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX/python:3.12
|
145
|
+
script:
|
146
|
+
- git clone --branch $BEC_CORE_BRANCH https://gitlab.psi.ch/bec/bec.git
|
147
|
+
- git clone --branch $OPHYD_DEVICES_BRANCH https://gitlab.psi.ch/bec/ophyd_devices.git
|
148
|
+
- export OHPYD_DEVICES_PATH=$PWD/ophyd_devices
|
149
|
+
- apt-get update
|
150
|
+
- apt-get install -y libgl1-mesa-glx libegl1-mesa x11-utils libxkbcommon-x11-0 libdbus-1-3
|
151
|
+
- pip install -e ./bec/bec_lib[dev]
|
152
|
+
- pip install -e .[dev,pyside6]
|
153
|
+
- pytest -v --junitxml=report.xml --random-order ./tests/unit_tests
|
154
|
+
allow_failure: true
|
155
|
+
|
156
|
+
tests-3.10-pyqt5:
|
157
|
+
extends: "tests"
|
158
|
+
stage: AdditionalTests
|
159
|
+
image: $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX/python:3.10
|
160
|
+
script:
|
161
|
+
- git clone --branch $BEC_CORE_BRANCH https://gitlab.psi.ch/bec/bec.git
|
162
|
+
- git clone --branch $OPHYD_DEVICES_BRANCH https://gitlab.psi.ch/bec/ophyd_devices.git
|
163
|
+
- export OHPYD_DEVICES_PATH=$PWD/ophyd_devices
|
164
|
+
- apt-get update
|
165
|
+
- apt-get install -y libgl1-mesa-glx libegl1-mesa x11-utils libxkbcommon-x11-0 libdbus-1-3
|
166
|
+
- pip install -e ./bec/bec_lib[dev]
|
167
|
+
- pip install -e .[dev,pyqt5]
|
168
|
+
- pytest -v --junitxml=report.xml --random-order ./tests/unit_tests
|
169
|
+
allow_failure: true
|
170
|
+
|
171
|
+
tests-3.11-pyqt5:
|
129
172
|
extends: "tests"
|
130
173
|
stage: AdditionalTests
|
131
174
|
image: $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX/python:3.11
|
175
|
+
script:
|
176
|
+
- git clone --branch $BEC_CORE_BRANCH https://gitlab.psi.ch/bec/bec.git
|
177
|
+
- git clone --branch $OPHYD_DEVICES_BRANCH https://gitlab.psi.ch/bec/ophyd_devices.git
|
178
|
+
- export OHPYD_DEVICES_PATH=$PWD/ophyd_devices
|
179
|
+
- apt-get update
|
180
|
+
- apt-get install -y libgl1-mesa-glx libegl1-mesa x11-utils libxkbcommon-x11-0 libdbus-1-3
|
181
|
+
- pip install -e ./bec/bec_lib[dev]
|
182
|
+
- pip install -e .[dev,pyqt5]
|
183
|
+
- pytest -v --junitxml=report.xml --random-order ./tests/unit_tests
|
132
184
|
allow_failure: true
|
133
185
|
|
134
|
-
tests-3.12:
|
186
|
+
tests-3.12-pyqt5:
|
135
187
|
extends: "tests"
|
136
188
|
stage: AdditionalTests
|
137
189
|
image: $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX/python:3.12
|
190
|
+
script:
|
191
|
+
- git clone --branch $BEC_CORE_BRANCH https://gitlab.psi.ch/bec/bec.git
|
192
|
+
- git clone --branch $OPHYD_DEVICES_BRANCH https://gitlab.psi.ch/bec/ophyd_devices.git
|
193
|
+
- export OHPYD_DEVICES_PATH=$PWD/ophyd_devices
|
194
|
+
- apt-get update
|
195
|
+
- apt-get install -y libgl1-mesa-glx libegl1-mesa x11-utils libxkbcommon-x11-0 libdbus-1-3
|
196
|
+
- pip install -e ./bec/bec_lib[dev]
|
197
|
+
- pip install -e .[dev,pyqt5]
|
198
|
+
- pytest -v --junitxml=report.xml --random-order ./tests/unit_tests
|
199
|
+
allow_failure: true
|
200
|
+
|
201
|
+
tests-3.10-pyqt6:
|
202
|
+
extends: "tests"
|
203
|
+
stage: AdditionalTests
|
204
|
+
image: $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX/python:3.10
|
205
|
+
script:
|
206
|
+
- git clone --branch $BEC_CORE_BRANCH https://gitlab.psi.ch/bec/bec.git
|
207
|
+
- git clone --branch $OPHYD_DEVICES_BRANCH https://gitlab.psi.ch/bec/ophyd_devices.git
|
208
|
+
- export OHPYD_DEVICES_PATH=$PWD/ophyd_devices
|
209
|
+
- apt-get update
|
210
|
+
- apt-get install -y libgl1-mesa-glx libegl1-mesa x11-utils libxkbcommon-x11-0 libdbus-1-3
|
211
|
+
- pip install -e ./bec/bec_lib[dev]
|
212
|
+
- pip install -e .[dev,pyqt6]
|
213
|
+
- pytest -v --junitxml=report.xml --random-order ./tests/unit_tests
|
214
|
+
allow_failure: true
|
215
|
+
|
216
|
+
tests-3.11-pyqt6:
|
217
|
+
extends: "tests"
|
218
|
+
stage: AdditionalTests
|
219
|
+
image: $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX/python:3.11
|
220
|
+
script:
|
221
|
+
- git clone --branch $BEC_CORE_BRANCH https://gitlab.psi.ch/bec/bec.git
|
222
|
+
- git clone --branch $OPHYD_DEVICES_BRANCH https://gitlab.psi.ch/bec/ophyd_devices.git
|
223
|
+
- export OHPYD_DEVICES_PATH=$PWD/ophyd_devices
|
224
|
+
- apt-get update
|
225
|
+
- apt-get install -y libgl1-mesa-glx libegl1-mesa x11-utils libxkbcommon-x11-0 libdbus-1-3
|
226
|
+
- pip install -e ./bec/bec_lib[dev]
|
227
|
+
- pip install -e .[dev,pyqt6]
|
228
|
+
- pytest -v --junitxml=report.xml --random-order ./tests/unit_tests
|
229
|
+
allow_failure: true
|
230
|
+
|
231
|
+
tests-3.12-pyqt6:
|
232
|
+
extends: "tests"
|
233
|
+
stage: AdditionalTests
|
234
|
+
image: $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX/python:3.12
|
235
|
+
script:
|
236
|
+
- git clone --branch $BEC_CORE_BRANCH https://gitlab.psi.ch/bec/bec.git
|
237
|
+
- git clone --branch $OPHYD_DEVICES_BRANCH https://gitlab.psi.ch/bec/ophyd_devices.git
|
238
|
+
- export OHPYD_DEVICES_PATH=$PWD/ophyd_devices
|
239
|
+
- apt-get update
|
240
|
+
- apt-get install -y libgl1-mesa-glx libegl1-mesa x11-utils libxkbcommon-x11-0 libdbus-1-3
|
241
|
+
- pip install -e ./bec/bec_lib[dev]
|
242
|
+
- pip install -e .[dev,pyqt6]
|
243
|
+
- pytest -v --junitxml=report.xml --random-order ./tests/unit_tests
|
138
244
|
allow_failure: true
|
139
245
|
|
140
246
|
end-2-end-conda:
|
@@ -150,7 +256,7 @@ end-2-end-conda:
|
|
150
256
|
- conda config --prepend channels conda-forge
|
151
257
|
- conda config --set channel_priority strict
|
152
258
|
- conda config --set always_yes yes --set changeps1 no
|
153
|
-
- conda create -q -n test-environment python=3.
|
259
|
+
- conda create -q -n test-environment python=3.11
|
154
260
|
- conda init bash
|
155
261
|
- source ~/.bashrc
|
156
262
|
- conda activate test-environment
|
@@ -183,7 +289,6 @@ end-2-end-conda:
|
|
183
289
|
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main"'
|
184
290
|
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "production"'
|
185
291
|
|
186
|
-
|
187
292
|
semver:
|
188
293
|
stage: Deploy
|
189
294
|
needs: ["tests"]
|
CHANGELOG.md
CHANGED
@@ -2,6 +2,40 @@
|
|
2
2
|
|
3
3
|
|
4
4
|
|
5
|
+
## v0.56.1 (2024-06-04)
|
6
|
+
|
7
|
+
### Fix
|
8
|
+
|
9
|
+
* fix(spiral_progress_bar/rings): config min/max values added check for floats ([`9d615c9`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/9d615c915c8f7cc2ea8f1dc17993b98fe462c682))
|
10
|
+
|
11
|
+
* fix(spiral_progress_bar): Endpoint is always stored as a string in the RingConnection Config ([`d253991`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/d2539918b296559e1d684344e179775a2423daa9))
|
12
|
+
|
13
|
+
|
14
|
+
## v0.56.0 (2024-05-29)
|
15
|
+
|
16
|
+
### Build
|
17
|
+
|
18
|
+
* build: added pyside6 as dependency ([`db301b1`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/db301b1be27bba76c8bb21fbff93cb4902b592a5))
|
19
|
+
|
20
|
+
### Ci
|
21
|
+
|
22
|
+
* ci: added tests for pyside6, pyqt6 and pyqt5, default test and e2e is python 3.11 and pyqt6 ([`855be35`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/855be3551a1372bcbebba6f8930903f99202bbca))
|
23
|
+
|
24
|
+
### Documentation
|
25
|
+
|
26
|
+
* docs(examples): example apps section deleted ([`ad208a5`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/ad208a5ef8495c45a8b83a4850ba9a1041b42717))
|
27
|
+
|
28
|
+
### Feature
|
29
|
+
|
30
|
+
* feat(utils/ui_loader): universal ui loader for pyside/pyqt ([`0fea8d6`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/0fea8d606574fa99dda3b117da5d5209c251f694))
|
31
|
+
|
32
|
+
### Fix
|
33
|
+
|
34
|
+
* fix(examples): outdated examples removed (mca_plot.py, stream_plot.py, motor_example.py) ([`ddc9510`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/ddc9510c2ba8dadf291809eeb5b135a105259492))
|
35
|
+
|
36
|
+
* fix: compatibility adjustment to .ui loading and tests for PySide6 ([`07b99d9`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/07b99d91a57a645cddd76294f48d78773e4c9ea5))
|
37
|
+
|
38
|
+
|
5
39
|
## v0.55.0 (2024-05-24)
|
6
40
|
|
7
41
|
### Feature
|
@@ -141,31 +175,3 @@
|
|
141
175
|
### Fix
|
142
176
|
|
143
177
|
* fix(cli): BECFigure takes the port to connect to redis from the current BECClient, supporting plugins ([`57cb136`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/57cb136a098e87a452414bf44e627edb562f6799))
|
144
|
-
|
145
|
-
|
146
|
-
## v0.50.0 (2024-04-29)
|
147
|
-
|
148
|
-
### Feature
|
149
|
-
|
150
|
-
* feat(plots): universal cleanup and remove also for children items ([`381d713`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/381d713837bb9217c58ba1d8b89691aa35c9f5ec))
|
151
|
-
|
152
|
-
* feat(rpc/rpc_register): singleton rpc register for all rpc connections for session ([`a898e7e`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/a898e7e4f14e9ae854703dddbd1eb8c50cb640ff))
|
153
|
-
|
154
|
-
### Fix
|
155
|
-
|
156
|
-
* fix(widgets/figure): access pattern changed for getting widgets by coordinates for rpc ([`13c018a`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/13c018a79704a7497c140df57179d294e43ecffa))
|
157
|
-
|
158
|
-
* fix(plots): cleanup policy reviewed for children items ([`8f20a0b`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/8f20a0b3b1b5dd117b36b45645717190b9ee9cbf))
|
159
|
-
|
160
|
-
* fix(rpc/client_utils): getoutput more transparent + error handling ([`6b6a6b2`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/6b6a6b2249f24d3d02bd5fcd7ef1c63ed794c304))
|
161
|
-
|
162
|
-
* fix(rpc_register): thread lock for listign all connections ([`2ca3267`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/2ca32675ec3f00137e2140259db51f6e5aa7bb71))
|
163
|
-
|
164
|
-
### Test
|
165
|
-
|
166
|
-
* test(cli/rpc_register): e2e RPCRegister ([`4f261be`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/4f261be4c7cfe54501443d031f9266f4f838f6e2))
|
167
|
-
|
168
|
-
* test(cli/rpc_register): rpc_register tests added ([`40eb75f`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/40eb75f85a4d99d498b086a37e799276a9d2ac3f))
|
169
|
-
|
170
|
-
|
171
|
-
## v0.49.1 (2024-04-26)
|
PKG-INFO
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: bec_widgets
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.56.1
|
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
|
@@ -31,3 +31,5 @@ Provides-Extra: pyqt5
|
|
31
31
|
Requires-Dist: pyqt5>=5.9; extra == 'pyqt5'
|
32
32
|
Provides-Extra: pyqt6
|
33
33
|
Requires-Dist: pyqt6>=6.7; extra == 'pyqt6'
|
34
|
+
Provides-Extra: pyside6
|
35
|
+
Requires-Dist: pyside6>=6.7; extra == 'pyside6'
|
@@ -2,18 +2,16 @@ import os
|
|
2
2
|
|
3
3
|
import numpy as np
|
4
4
|
import pyqtgraph as pg
|
5
|
-
|
5
|
+
import qdarktheme
|
6
6
|
from qtconsole.inprocess import QtInProcessKernelManager
|
7
7
|
from qtconsole.rich_jupyter_widget import RichJupyterWidget
|
8
8
|
from qtpy.QtCore import QSize
|
9
9
|
from qtpy.QtGui import QIcon
|
10
10
|
from qtpy.QtWidgets import QApplication, QVBoxLayout, QWidget
|
11
11
|
|
12
|
-
from bec_widgets.
|
13
|
-
from bec_widgets.utils import BECDispatcher
|
12
|
+
from bec_widgets.utils import BECDispatcher, UILoader
|
14
13
|
from bec_widgets.widgets import BECFigure
|
15
14
|
from bec_widgets.widgets.dock.dock_area import BECDockArea
|
16
|
-
from bec_widgets.widgets.spiral_progress_bar.spiral_progress_bar import SpiralProgressBar
|
17
15
|
|
18
16
|
|
19
17
|
class JupyterConsoleWidget(RichJupyterWidget): # pragma: no cover:
|
@@ -26,7 +24,6 @@ class JupyterConsoleWidget(RichJupyterWidget): # pragma: no cover:
|
|
26
24
|
self.kernel_client.start_channels()
|
27
25
|
|
28
26
|
self.kernel_manager.kernel.shell.push({"np": np, "pg": pg})
|
29
|
-
# self.set_console_font_size(70)
|
30
27
|
|
31
28
|
def shutdown_kernel(self):
|
32
29
|
self.kernel_client.stop_channels()
|
@@ -40,33 +37,28 @@ class JupyterConsoleWindow(QWidget): # pragma: no cover:
|
|
40
37
|
super().__init__(parent)
|
41
38
|
|
42
39
|
current_path = os.path.dirname(__file__)
|
43
|
-
|
40
|
+
self.ui = UILoader().load_ui(os.path.join(current_path, "jupyter_console_window.ui"), self)
|
44
41
|
|
45
42
|
self._init_ui()
|
46
43
|
|
47
|
-
self.splitter.setSizes([200, 100])
|
44
|
+
self.ui.splitter.setSizes([200, 100])
|
48
45
|
self.safe_close = False
|
49
|
-
# self.figure.clean_signal.connect(self.confirm_close)
|
50
|
-
|
51
|
-
self.register = RPCRegister()
|
52
|
-
self.register.add_rpc(self.figure)
|
53
46
|
|
54
47
|
# console push
|
55
48
|
self.console.kernel_manager.kernel.shell.push(
|
56
49
|
{
|
57
50
|
"fig": self.figure,
|
58
|
-
"register": self.register,
|
59
51
|
"dock": self.dock,
|
60
52
|
"w1": self.w1,
|
61
53
|
"w2": self.w2,
|
62
54
|
"w3": self.w3,
|
55
|
+
"d0": self.d0,
|
63
56
|
"d1": self.d1,
|
64
57
|
"d2": self.d2,
|
65
|
-
"
|
58
|
+
"fig0": self.fig0,
|
59
|
+
"fig1": self.fig1,
|
60
|
+
"fig2": self.fig2,
|
66
61
|
"bar": self.bar,
|
67
|
-
"b2a": self.button_2_a,
|
68
|
-
"b2b": self.button_2_b,
|
69
|
-
"b2c": self.button_2_c,
|
70
62
|
"bec": self.figure.client,
|
71
63
|
"scans": self.figure.client.scans,
|
72
64
|
"dev": self.figure.client.device_manager.devices,
|
@@ -75,11 +67,11 @@ class JupyterConsoleWindow(QWidget): # pragma: no cover:
|
|
75
67
|
|
76
68
|
def _init_ui(self):
|
77
69
|
# Plotting window
|
78
|
-
self.glw_1_layout = QVBoxLayout(self.glw) # Create a new QVBoxLayout
|
70
|
+
self.glw_1_layout = QVBoxLayout(self.ui.glw) # Create a new QVBoxLayout
|
79
71
|
self.figure = BECFigure(parent=self, gui_id="remote") # Create a new BECDeviceMonitor
|
80
72
|
self.glw_1_layout.addWidget(self.figure) # Add BECDeviceMonitor to the layout
|
81
73
|
|
82
|
-
self.dock_layout = QVBoxLayout(self.dock_placeholder)
|
74
|
+
self.dock_layout = QVBoxLayout(self.ui.dock_placeholder)
|
83
75
|
self.dock = BECDockArea(gui_id="remote")
|
84
76
|
self.dock_layout.addWidget(self.dock)
|
85
77
|
|
@@ -89,7 +81,7 @@ class JupyterConsoleWindow(QWidget): # pragma: no cover:
|
|
89
81
|
# init dock for testing
|
90
82
|
self._init_dock()
|
91
83
|
|
92
|
-
self.console_layout = QVBoxLayout(self.widget_console)
|
84
|
+
self.console_layout = QVBoxLayout(self.ui.widget_console)
|
93
85
|
self.console = JupyterConsoleWidget()
|
94
86
|
self.console_layout.addWidget(self.console)
|
95
87
|
self.console.set_default_style("linux")
|
@@ -111,25 +103,22 @@ class JupyterConsoleWindow(QWidget): # pragma: no cover:
|
|
111
103
|
self.c1 = self.w1.get_config()
|
112
104
|
|
113
105
|
def _init_dock(self):
|
114
|
-
|
115
|
-
self.
|
116
|
-
self.
|
117
|
-
self.
|
118
|
-
|
119
|
-
self.
|
120
|
-
|
121
|
-
self.
|
122
|
-
self.
|
123
|
-
|
124
|
-
self.
|
125
|
-
self.
|
126
|
-
self.
|
127
|
-
self.
|
128
|
-
self.
|
129
|
-
self.
|
130
|
-
self.d3.add_widget(self.label_3)
|
131
|
-
self.d3.add_widget(self.button_3)
|
132
|
-
self.d3.add_widget(self.fig_dock3)
|
106
|
+
|
107
|
+
self.d0 = self.dock.add_dock(name="dock_0")
|
108
|
+
self.fig0 = self.d0.add_widget_bec("BECFigure")
|
109
|
+
self.fig0.image("eiger", vrange=(0, 100))
|
110
|
+
|
111
|
+
self.d1 = self.dock.add_dock(name="dock_1", position="right")
|
112
|
+
self.fig1 = self.d1.add_widget_bec("BECFigure")
|
113
|
+
self.fig1.plot(x_name="samx", y_name="bpm4i")
|
114
|
+
self.fig1.plot(x_name="samx", y_name="bpm3a")
|
115
|
+
|
116
|
+
self.d2 = self.dock.add_dock(name="dock_2", position="bottom")
|
117
|
+
self.fig2 = self.d2.add_widget_bec("BECFigure", row=0, col=0)
|
118
|
+
self.fig2.motor_map(x_name="samx", y_name="samy")
|
119
|
+
self.fig2.plot(x_name="samx", y_name="bpm4i")
|
120
|
+
self.bar = self.d2.add_widget_bec("SpiralProgressBar", row=0, col=1)
|
121
|
+
self.bar.set_diameter(200)
|
133
122
|
|
134
123
|
self.dock.save_state()
|
135
124
|
|
@@ -155,6 +144,7 @@ if __name__ == "__main__": # pragma: no cover
|
|
155
144
|
app = QApplication(sys.argv)
|
156
145
|
app.setApplicationName("Jupyter Console")
|
157
146
|
app.setApplicationDisplayName("Jupyter Console")
|
147
|
+
qdarktheme.setup_theme("auto")
|
158
148
|
icon = QIcon()
|
159
149
|
icon.addFile(os.path.join(module_path, "assets", "terminal_icon.png"), size=QSize(48, 48))
|
160
150
|
app.setWindowIcon(icon)
|
@@ -151,7 +151,7 @@ class MotorControlPanel(QWidget):
|
|
151
151
|
self.selection_widget.selected_motors_signal.connect(self.absolute_widget.change_motors)
|
152
152
|
|
153
153
|
# Set the window to a fixed size based on its contents
|
154
|
-
self.layout().setSizeConstraint(layout.SetFixedSize)
|
154
|
+
# self.layout().setSizeConstraint(layout.SetFixedSize)
|
155
155
|
|
156
156
|
|
157
157
|
class MotorControlPanelAbsolute(QWidget):
|
@@ -178,9 +178,6 @@ class MotorControlPanelAbsolute(QWidget):
|
|
178
178
|
# Connecting signals and slots
|
179
179
|
self.selection_widget.selected_motors_signal.connect(self.absolute_widget.change_motors)
|
180
180
|
|
181
|
-
# Set the window to a fixed size based on its contents
|
182
|
-
self.layout().setSizeConstraint(layout.SetFixedSize)
|
183
|
-
|
184
181
|
|
185
182
|
class MotorControlPanelRelative(QWidget):
|
186
183
|
def __init__(self, parent=None, client=None, config=None):
|
@@ -206,9 +203,6 @@ class MotorControlPanelRelative(QWidget):
|
|
206
203
|
# Connecting signals and slots
|
207
204
|
self.selection_widget.selected_motors_signal.connect(self.relative_widget.change_motors)
|
208
205
|
|
209
|
-
# Set the window to a fixed size based on its contents
|
210
|
-
self.layout().setSizeConstraint(layout.SetFixedSize)
|
211
|
-
|
212
206
|
|
213
207
|
if __name__ == "__main__": # pragma: no cover
|
214
208
|
import argparse
|
bec_widgets/utils/__init__.py
CHANGED
@@ -7,4 +7,5 @@ from .crosshair import Crosshair
|
|
7
7
|
from .entry_validator import EntryValidator
|
8
8
|
from .layout_manager import GridLayoutManager
|
9
9
|
from .rpc_decorator import register_rpc_methods, rpc_public
|
10
|
+
from .ui_loader import UILoader
|
10
11
|
from .validator_delegate import DoubleValidationDelegate
|
bec_widgets/utils/crosshair.py
CHANGED
@@ -8,13 +8,13 @@ from qtpy.QtCore import Signal as pyqtSignal
|
|
8
8
|
|
9
9
|
class Crosshair(QObject):
|
10
10
|
# Signal for 1D plot
|
11
|
-
coordinatesChanged1D = pyqtSignal(
|
12
|
-
coordinatesClicked1D = pyqtSignal(
|
11
|
+
coordinatesChanged1D = pyqtSignal(tuple)
|
12
|
+
coordinatesClicked1D = pyqtSignal(tuple)
|
13
13
|
# Signal for 2D plot
|
14
|
-
coordinatesChanged2D = pyqtSignal(
|
15
|
-
coordinatesClicked2D = pyqtSignal(
|
14
|
+
coordinatesChanged2D = pyqtSignal(tuple)
|
15
|
+
coordinatesClicked2D = pyqtSignal(tuple)
|
16
16
|
|
17
|
-
def __init__(self, plot_item: pg.PlotItem, precision: int =
|
17
|
+
def __init__(self, plot_item: pg.PlotItem, precision: int = 3, parent=None):
|
18
18
|
"""
|
19
19
|
Crosshair for 1D and 2D plots.
|
20
20
|
|
@@ -174,10 +174,11 @@ class Crosshair(QObject):
|
|
174
174
|
if isinstance(item, pg.PlotDataItem):
|
175
175
|
if x is None or all(v is None for v in y_values):
|
176
176
|
return
|
177
|
-
|
177
|
+
coordinate_to_emit = (
|
178
178
|
round(x, self.precision),
|
179
179
|
[round(y_val, self.precision) for y_val in y_values],
|
180
180
|
)
|
181
|
+
self.coordinatesChanged1D.emit(coordinate_to_emit)
|
181
182
|
for i, y_val in enumerate(y_values):
|
182
183
|
self.marker_moved_1d[i].setData(
|
183
184
|
[x if not self.is_log_x else np.log10(x)],
|
@@ -186,7 +187,8 @@ class Crosshair(QObject):
|
|
186
187
|
elif isinstance(item, pg.ImageItem):
|
187
188
|
if x is None or y_values is None:
|
188
189
|
return
|
189
|
-
|
190
|
+
coordinate_to_emit = (x, y_values)
|
191
|
+
self.coordinatesChanged2D.emit(coordinate_to_emit)
|
190
192
|
|
191
193
|
def mouse_clicked(self, event):
|
192
194
|
"""Handles the mouse clicked event, updating the crosshair position and emitting signals.
|
@@ -209,10 +211,11 @@ class Crosshair(QObject):
|
|
209
211
|
if isinstance(item, pg.PlotDataItem):
|
210
212
|
if x is None or all(v is None for v in y_values):
|
211
213
|
return
|
212
|
-
|
214
|
+
coordinate_to_emit = (
|
213
215
|
round(x, self.precision),
|
214
216
|
[round(y_val, self.precision) for y_val in y_values],
|
215
217
|
)
|
218
|
+
self.coordinatesClicked1D.emit(coordinate_to_emit)
|
216
219
|
for i, y_val in enumerate(y_values):
|
217
220
|
for marker in self.marker_clicked_1d[i]:
|
218
221
|
marker.setData(
|
@@ -222,7 +225,8 @@ class Crosshair(QObject):
|
|
222
225
|
elif isinstance(item, pg.ImageItem):
|
223
226
|
if x is None or y_values is None:
|
224
227
|
return
|
225
|
-
|
228
|
+
coordinate_to_emit = (x, y_values)
|
229
|
+
self.coordinatesClicked2D.emit(coordinate_to_emit)
|
226
230
|
self.marker_2d.setPos([x, y_values])
|
227
231
|
|
228
232
|
def check_log(self):
|
@@ -0,0 +1,58 @@
|
|
1
|
+
from qtpy import QT_VERSION
|
2
|
+
from qtpy.QtCore import QFile, QIODevice
|
3
|
+
|
4
|
+
|
5
|
+
class UILoader:
|
6
|
+
"""Universal UI loader for PyQt5, PyQt6, PySide2, and PySide6."""
|
7
|
+
|
8
|
+
def __init__(self, parent=None):
|
9
|
+
self.parent = parent
|
10
|
+
if QT_VERSION.startswith("5"):
|
11
|
+
# PyQt5 or PySide2
|
12
|
+
from qtpy import uic
|
13
|
+
|
14
|
+
self.loader = uic.loadUi
|
15
|
+
elif QT_VERSION.startswith("6"):
|
16
|
+
# PyQt6 or PySide6
|
17
|
+
try:
|
18
|
+
from PySide6.QtUiTools import QUiLoader
|
19
|
+
|
20
|
+
self.loader = self.load_ui_pyside6
|
21
|
+
except ImportError:
|
22
|
+
from PyQt6.uic import loadUi
|
23
|
+
|
24
|
+
self.loader = loadUi
|
25
|
+
|
26
|
+
def load_ui_pyside6(self, ui_file, parent=None):
|
27
|
+
"""
|
28
|
+
Specific loader for PySide6 using QUiLoader.
|
29
|
+
Args:
|
30
|
+
ui_file(str): Path to the .ui file.
|
31
|
+
parent(QWidget): Parent widget.
|
32
|
+
|
33
|
+
Returns:
|
34
|
+
QWidget: The loaded widget.
|
35
|
+
"""
|
36
|
+
from PySide6.QtUiTools import QUiLoader
|
37
|
+
|
38
|
+
loader = QUiLoader(parent)
|
39
|
+
file = QFile(ui_file)
|
40
|
+
if not file.open(QIODevice.ReadOnly):
|
41
|
+
raise IOError(f"Cannot open file: {ui_file}")
|
42
|
+
widget = loader.load(file, parent)
|
43
|
+
file.close()
|
44
|
+
return widget
|
45
|
+
|
46
|
+
def load_ui(self, ui_file, parent=None):
|
47
|
+
"""
|
48
|
+
Universal UI loader method.
|
49
|
+
Args:
|
50
|
+
ui_file(str): Path to the .ui file.
|
51
|
+
parent(QWidget): Parent widget.
|
52
|
+
|
53
|
+
Returns:
|
54
|
+
QWidget: The loaded widget.
|
55
|
+
"""
|
56
|
+
if parent is None:
|
57
|
+
parent = self.parent
|
58
|
+
return self.loader(ui_file, parent)
|