bec-widgets 1.3.3__py3-none-any.whl → 1.4.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.
CHANGELOG.md CHANGED
@@ -1,170 +1,209 @@
1
1
  # CHANGELOG
2
2
 
3
3
 
4
+ ## v1.4.1 (2024-11-12)
5
+
6
+ ### Bug Fixes
7
+
8
+ - **positioner_box**: Adjusted default signals
9
+ ([`8e5c0ad`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/8e5c0ad8c8eff5a9308169bc663d2b7230f0ebb1))
10
+
11
+
12
+ ## v1.4.0 (2024-11-11)
13
+
14
+ ### Bug Fixes
15
+
16
+ - **crosshair**: Label of coordinates of TextItem displays numbers in general format
17
+ ([`11e5937`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/11e5937ae0f3c1413acd4e66878a692ebe4ef7d0))
18
+
19
+ - **crosshair**: Label of coordinates of TextItem is updated according to the current theme of qapp
20
+ ([`4f31ea6`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/4f31ea655cf6190e141e6a2720a2d6da517a2b5b))
21
+
22
+ - **crosshair**: Log is separately scaled for backend logic and for signal emit
23
+ ([`b2eb71a`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/b2eb71aae0b6a7c82158f2d150ae1e31411cfdeb))
24
+
25
+ ### Features
26
+
27
+ - **crosshair**: Textitem to display crosshair coordinates
28
+ ([`035136d`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/035136d5171ec5f4311d15a9aa5bad2bdbc1f6cb))
29
+
30
+ ### Testing
31
+
32
+ - **crosshair**: Tests extended
33
+ ([`64df805`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/64df805a9ed92bb97e580ac3bc0a1bbd2b1cb81e))
34
+
35
+
4
36
  ## v1.3.3 (2024-11-07)
5
37
 
6
38
  ### Bug Fixes
7
39
 
8
- * fix(scan_control): DeviceLineEdit kwargs readings changed to get name of the positioner ([`5fabd4b`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/5fabd4bea95bafd2352102686357cc1db80813fd))
40
+ - **scan_control**: Devicelineedit kwargs readings changed to get name of the positioner
41
+ ([`5fabd4b`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/5fabd4bea95bafd2352102686357cc1db80813fd))
9
42
 
10
43
  ### Documentation
11
44
 
12
- * docs: update outdated text in docs ([`4f0693c`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/4f0693cae34b391d75884837e1ae6353a0501868))
45
+ - Update outdated text in docs
46
+ ([`4f0693c`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/4f0693cae34b391d75884837e1ae6353a0501868))
13
47
 
14
48
 
15
49
  ## v1.3.2 (2024-11-05)
16
50
 
17
51
  ### Bug Fixes
18
52
 
19
- * fix(plot_base): legend text color is changed when changing dark-light theme ([`2304c9f`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/2304c9f8497c1ab1492f3e6690bb79b0464c0df8))
53
+ - **plot_base**: Legend text color is changed when changing dark-light theme
54
+ ([`2304c9f`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/2304c9f8497c1ab1492f3e6690bb79b0464c0df8))
20
55
 
21
56
  ### Build System
22
57
 
23
- * build: PySide6 version fixed 6.7.2 ([`c6e48ec`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/c6e48ec1fe5aaee6a7c7a6f930f1520cd439cdb2))
58
+ - Pyside6 version fixed 6.7.2
59
+ ([`c6e48ec`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/c6e48ec1fe5aaee6a7c7a6f930f1520cd439cdb2))
24
60
 
25
61
 
26
62
  ## v1.3.1 (2024-10-31)
27
63
 
28
64
  ### Bug Fixes
29
65
 
30
- * fix(ophyd_kind_util): Kind enums are imported from the bec widget util class ([`940ee65`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/940ee6552c1ee8d9b4e4a74c62351f2e133ab678))
66
+ - **ophyd_kind_util**: Kind enums are imported from the bec widget util class
67
+ ([`940ee65`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/940ee6552c1ee8d9b4e4a74c62351f2e133ab678))
31
68
 
32
69
 
33
70
  ## v1.3.0 (2024-10-30)
34
71
 
35
72
  ### Bug Fixes
36
73
 
37
- * fix(colors): extend color map validation for matplotlib and colorcet maps (if available) ([`14dd8c5`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/14dd8c5b2947c92f6643b888d71975e4e8d4ee88))
74
+ - **colors**: Extend color map validation for matplotlib and colorcet maps (if available)
75
+ ([`14dd8c5`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/14dd8c5b2947c92f6643b888d71975e4e8d4ee88))
38
76
 
39
77
  ### Features
40
78
 
41
- * feat(colormap_button): colormap button with menu to select colormap filtered by the colormap type ([`b039933`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/b039933405e2fbe92bd81bd0748e79e8d443a741))
79
+ - **colormap_button**: Colormap button with menu to select colormap filtered by the colormap type
80
+ ([`b039933`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/b039933405e2fbe92bd81bd0748e79e8d443a741))
42
81
 
43
82
 
44
83
  ## v1.2.0 (2024-10-25)
45
84
 
46
85
  ### Features
47
86
 
48
- * feat(colors): evenly spaced color generation + new golden ratio calculation ([`40c9fea`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/40c9fea35f869ef52e05948dd1989bcd99f602e0))
87
+ - **colors**: Evenly spaced color generation + new golden ratio calculation
88
+ ([`40c9fea`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/40c9fea35f869ef52e05948dd1989bcd99f602e0))
49
89
 
50
90
  ### Refactoring
51
91
 
52
- * refactor: add bec_lib version to statusbox ([`5d4b86e`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/5d4b86e1c6e1800051afce4f991153e370767fa6))
92
+ - Add bec_lib version to statusbox
93
+ ([`5d4b86e`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/5d4b86e1c6e1800051afce4f991153e370767fa6))
53
94
 
54
95
 
55
96
  ## v1.1.0 (2024-10-25)
56
97
 
57
98
  ### Features
58
99
 
59
- * feat: add filter i/o utility class ([`0350833`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/0350833f36e0a7cadce4173f9b1d1fbfdf985375))
100
+ - Add filter i/o utility class
101
+ ([`0350833`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/0350833f36e0a7cadce4173f9b1d1fbfdf985375))
60
102
 
61
103
  ### Refactoring
62
104
 
63
- * refactor: do not flush selection upon receiving config update; allow widgetIO to receive kwargs to be able to use get_value to receive string instead of int for QComboBox ([`91959e8`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/91959e82de8586934af3ebb5aaa0923930effc51))
105
+ - Do not flush selection upon receiving config update; allow widgetIO to receive kwargs to be able
106
+ to use get_value to receive string instead of int for QComboBox
107
+ ([`91959e8`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/91959e82de8586934af3ebb5aaa0923930effc51))
64
108
 
65
- * refactor: allow to set selection in DeviceInput; automatic update of selection on device config update; cleanup ([`5eb15b7`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/5eb15b785f12e30eb8ccbc56d4ad9e759a4cf5eb))
109
+ - Allow to set selection in DeviceInput; automatic update of selection on device config update;
110
+ cleanup
111
+ ([`5eb15b7`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/5eb15b785f12e30eb8ccbc56d4ad9e759a4cf5eb))
66
112
 
67
- * refactor: cleanup, added device_signal for signal inputs ([`6fb2055`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/6fb20552ff57978f4aeb79fd7f062f8d6b5581e7))
113
+ - Cleanup, added device_signal for signal inputs
114
+ ([`6fb2055`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/6fb20552ff57978f4aeb79fd7f062f8d6b5581e7))
68
115
 
69
116
  ### Testing
70
117
 
71
- * test(scan_control): tests added for grid_scan to ensure scan_args signal validity ([`acb7902`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/acb79020d4be546efc001ff47b6f5cdba2ee9375))
118
+ - **scan_control**: Tests added for grid_scan to ensure scan_args signal validity
119
+ ([`acb7902`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/acb79020d4be546efc001ff47b6f5cdba2ee9375))
72
120
 
73
121
 
74
122
  ## v1.0.2 (2024-10-22)
75
123
 
76
124
  ### Bug Fixes
77
125
 
78
- * fix(scan_control): scan args signal fixed to emit list instead of hardcoded structure ([`4f5448c`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/4f5448cf51a204e077af162c7f0aed1f1a60e57a))
126
+ - **scan_control**: Scan args signal fixed to emit list instead of hardcoded structure
127
+ ([`4f5448c`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/4f5448cf51a204e077af162c7f0aed1f1a60e57a))
79
128
 
80
129
 
81
130
  ## v1.0.1 (2024-10-22)
82
131
 
83
132
  ### Bug Fixes
84
133
 
85
- * fix(waveform): added support for live_data and data access ([`7469c89`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/7469c892c8076fc09e61f173df6920c551241cec))
134
+ - **waveform**: Added support for live_data and data access
135
+ ([`7469c89`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/7469c892c8076fc09e61f173df6920c551241cec))
86
136
 
87
137
 
88
138
  ## v1.0.0 (2024-10-18)
89
139
 
90
- ### Breaking
140
+ ### Bug Fixes
91
141
 
92
- * feat!: ability to disable scatter from waveform & compatible crosshair with down sampling ([`2ab12ed`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/2ab12ed60abb995abc381d9330fdcf399796d9e5))
142
+ - **crosshair**: Downsample clear markers
143
+ ([`f9a889f`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/f9a889fc6d380b9e587edcb465203122ea0bffc1))
93
144
 
94
- ### Bug Fixes
145
+ ### Features
95
146
 
96
- * fix(crosshair): downsample clear markers ([`f9a889f`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/f9a889fc6d380b9e587edcb465203122ea0bffc1))
147
+ - Ability to disable scatter from waveform & compatible crosshair with down sampling
148
+ ([`2ab12ed`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/2ab12ed60abb995abc381d9330fdcf399796d9e5))
97
149
 
98
150
 
99
151
  ## v0.119.0 (2024-10-17)
100
152
 
101
153
  ### Bug Fixes
102
154
 
103
- * fix: fix syntax due to change of api for simulated devices ([`19f4e40`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/19f4e407e00ee242973ca4c3f90e4e41a4d3e315))
155
+ - Fix syntax due to change of api for simulated devices
156
+ ([`19f4e40`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/19f4e407e00ee242973ca4c3f90e4e41a4d3e315))
104
157
 
105
- * fix: remove wrongly scoped test ([`a23841b`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/a23841b2553dc7162da943715d58275c7dc39ed9))
158
+ - Remove wrongly scoped test
159
+ ([`a23841b`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/a23841b2553dc7162da943715d58275c7dc39ed9))
106
160
 
107
- * fix: rename 'compact' property -> 'compact_view' ([`6982711`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/6982711fea5fb8a73845ed7c0692e3ec53ef7871))
161
+ - Rename 'compact' property -> 'compact_view'
162
+ ([`6982711`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/6982711fea5fb8a73845ed7c0692e3ec53ef7871))
108
163
 
109
- * fix: Alignment 1D update, make app window a main window (in .ui file) ([`0015f0e`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/0015f0e2d62adc02d3ef334e1f6dbb2d0288fec6))
164
+ - Alignment 1D update, make app window a main window (in .ui file)
165
+ ([`0015f0e`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/0015f0e2d62adc02d3ef334e1f6dbb2d0288fec6))
110
166
 
111
- * fix: set (Minimum, Fixed) size policy on Stop button ([`523cc43`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/523cc435725b10b7d59a4477a1aaa24a1f3e37a2))
167
+ - Set (Minimum, Fixed) size policy on Stop button
168
+ ([`523cc43`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/523cc435725b10b7d59a4477a1aaa24a1f3e37a2))
112
169
 
113
170
  ### Features
114
171
 
115
- * feat: new PositionerGroup widget ([`af9655d`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/af9655de0c541092437accfbaa779628a2f48ccb))
172
+ - New PositionerGroup widget
173
+ ([`af9655d`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/af9655de0c541092437accfbaa779628a2f48ccb))
116
174
 
117
- * feat: add 'expand_popup' property to CompactPopupWidget
175
+ - Add 'expand_popup' property to CompactPopupWidget
176
+ ([`e4121a0`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/e4121a01cb6b8d496e630cd43bc642b994b8f310))
118
177
 
119
- This property tells if expand should show a popup (by default), or
120
- if the widget should expand in-place ([`e4121a0`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/e4121a01cb6b8d496e630cd43bc642b994b8f310))
178
+ This property tells if expand should show a popup (by default), or if the widget should expand
179
+ in-place
121
180
 
122
- * feat: PositionerBox with a popup view ([`2615787`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/261578796f1de8ca9cab9b91659bc1484f7aa89d))
181
+ - Positionerbox with a popup view
182
+ ([`2615787`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/261578796f1de8ca9cab9b91659bc1484f7aa89d))
123
183
 
124
- * feat: emit 'device_selected' and 'scan_axis' from scan control widget ([`0b9b1a3`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/0b9b1a3c89a98505079f7d4078915b7bbfaa1e23))
184
+ - Emit 'device_selected' and 'scan_axis' from scan control widget
185
+ ([`0b9b1a3`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/0b9b1a3c89a98505079f7d4078915b7bbfaa1e23))
125
186
 
126
- * feat: new 'device_selected' signals to ScanControl, ScanGroupBox, DeviceLineEdit ([`9801d27`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/9801d2769eb0ee95c94ec0c011e1dac1407142ae))
187
+ - New 'device_selected' signals to ScanControl, ScanGroupBox, DeviceLineEdit
188
+ ([`9801d27`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/9801d2769eb0ee95c94ec0c011e1dac1407142ae))
127
189
 
128
190
  ### Refactoring
129
191
 
130
- * refactor: redesign of scan selection and scan control boxes ([`a69d287`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/a69d2870e2b3539739781d741b27b8599c0f4abd))
192
+ - Redesign of scan selection and scan control boxes
193
+ ([`a69d287`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/a69d2870e2b3539739781d741b27b8599c0f4abd))
131
194
 
132
- * refactor: move add/remove bundle to scan group box ([`e3d0a7b`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/e3d0a7bbf9918dc16eb7227a178c310256ce570d))
195
+ - Move add/remove bundle to scan group box
196
+ ([`e3d0a7b`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/e3d0a7bbf9918dc16eb7227a178c310256ce570d))
133
197
 
134
198
 
135
199
  ## v0.118.0 (2024-10-13)
136
200
 
137
201
  ### Documentation
138
202
 
139
- * docs(sphinx-build): adjusted pyside verion ([`b236951`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/b23695167ab969f754a058ffdccca2b40f00a008))
203
+ - **sphinx-build**: Adjusted pyside verion
204
+ ([`b236951`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/b23695167ab969f754a058ffdccca2b40f00a008))
140
205
 
141
206
  ### Features
142
207
 
143
- * feat(image): image widget can take data from monitor_1d endpoint ([`9ef1d1c`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/9ef1d1c9ac2178d9fa2e655942208f8abbdf5c1b))
144
-
145
-
146
- ## v0.117.1 (2024-10-11)
147
-
148
- ### Bug Fixes
149
-
150
- * fix(FPS): qtimer cleanup leaking ([`3a22392`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/3a2239278075de7489ad10a58c31d7d89715e221))
151
-
152
- ### Unknown
153
-
154
- * feature(vscode): added support for vscode instructions ([`f5f1f6c`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/f5f1f6c304b890dc162e8653005233bce4ea82e4))
155
-
156
- * feature(vscode): support for controlling vscode from widgets ([`9238679`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/923867947f62db026ac0378c30ef62c883596058))
157
-
158
-
159
- ## v0.117.0 (2024-10-11)
160
-
161
- ### Features
162
-
163
- * feat(utils): FPS counter utility based on the viewBox updates, integrated to waveform and image widget ([`8c5ef26`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/8c5ef268430d5243ac05fcbbdb6b76ad24ac5735))
164
-
165
- ### Unknown
166
-
167
- * tests(plot_base): tests extended ([`8dc892d`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/8dc892df0a47ccbdd812555b7c5775a455a23ede))
168
-
169
-
170
- ## v0.116.0 (2024-10-11)
208
+ - **image**: Image widget can take data from monitor_1d endpoint
209
+ ([`9ef1d1c`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/9ef1d1c9ac2178d9fa2e655942208f8abbdf5c1b))
PKG-INFO CHANGED
@@ -1,10 +1,9 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bec_widgets
3
- Version: 1.3.3
3
+ Version: 1.4.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
7
- License-File: LICENSE
8
7
  Classifier: Development Status :: 3 - Alpha
9
8
  Classifier: Programming Language :: Python :: 3
10
9
  Classifier: Topic :: Scientific/Engineering
@@ -2,10 +2,8 @@ from collections import defaultdict
2
2
 
3
3
  import numpy as np
4
4
  import pyqtgraph as pg
5
-
6
- # from qtpy.QtCore import QObject, pyqtSignal
7
- from qtpy.QtCore import QObject, Qt
8
- from qtpy.QtCore import Signal as pyqtSignal
5
+ from qtpy.QtCore import QObject, Qt, Signal, Slot
6
+ from qtpy.QtWidgets import QApplication
9
7
 
10
8
 
11
9
  class NonDownsamplingScatterPlotItem(pg.ScatterPlotItem):
@@ -17,14 +15,18 @@ class NonDownsamplingScatterPlotItem(pg.ScatterPlotItem):
17
15
 
18
16
 
19
17
  class Crosshair(QObject):
20
- positionChanged = pyqtSignal(tuple)
21
- positionClicked = pyqtSignal(tuple)
18
+ # QT Position of mouse cursor
19
+ positionChanged = Signal(tuple)
20
+ positionClicked = Signal(tuple)
21
+ # Plain crosshair position signals mapped to real coordinates
22
+ crosshairChanged = Signal(tuple)
23
+ crosshairClicked = Signal(tuple)
22
24
  # Signal for 1D plot
23
- coordinatesChanged1D = pyqtSignal(tuple)
24
- coordinatesClicked1D = pyqtSignal(tuple)
25
+ coordinatesChanged1D = Signal(tuple)
26
+ coordinatesClicked1D = Signal(tuple)
25
27
  # Signal for 2D plot
26
- coordinatesChanged2D = pyqtSignal(tuple)
27
- coordinatesClicked2D = pyqtSignal(tuple)
28
+ coordinatesChanged2D = Signal(tuple)
29
+ coordinatesClicked2D = Signal(tuple)
28
30
 
29
31
  def __init__(self, plot_item: pg.PlotItem, precision: int = 3, parent=None):
30
32
  """
@@ -47,11 +49,21 @@ class Crosshair(QObject):
47
49
  self.h_line.skip_auto_range = True
48
50
  self.plot_item.addItem(self.v_line, ignoreBounds=True)
49
51
  self.plot_item.addItem(self.h_line, ignoreBounds=True)
52
+
53
+ # Add TextItem to display coordinates
54
+ self.coord_label = pg.TextItem("", anchor=(1, 1), fill=(0, 0, 0, 100))
55
+ self.coord_label.setVisible(False) # Hide initially
56
+ self.coord_label.skip_auto_range = True
57
+ self.plot_item.addItem(self.coord_label)
58
+
59
+ # Signals to connect
50
60
  self.proxy = pg.SignalProxy(
51
61
  self.plot_item.scene().sigMouseMoved, rateLimit=60, slot=self.mouse_moved
52
62
  )
63
+ self.positionChanged.connect(self.update_coord_label)
53
64
  self.plot_item.scene().sigMouseClicked.connect(self.mouse_clicked)
54
65
 
66
+ # Connect signals from pyqtgraph right click menu
55
67
  self.plot_item.ctrl.derivativeCheck.checkStateChanged.connect(self.check_derivatives)
56
68
  self.plot_item.ctrl.logXCheck.checkStateChanged.connect(self.check_log)
57
69
  self.plot_item.ctrl.logYCheck.checkStateChanged.connect(self.check_log)
@@ -62,6 +74,44 @@ class Crosshair(QObject):
62
74
  self.marker_clicked_1d = {}
63
75
  self.marker_2d = None
64
76
  self.update_markers()
77
+ self.check_log()
78
+ self.check_derivatives()
79
+
80
+ self._connect_to_theme_change()
81
+
82
+ def _connect_to_theme_change(self):
83
+ """Connect to the theme change signal."""
84
+ qapp = QApplication.instance()
85
+ if hasattr(qapp, "theme_signal"):
86
+ qapp.theme_signal.theme_updated.connect(self._update_theme)
87
+ self._update_theme()
88
+
89
+ @Slot(str)
90
+ def _update_theme(self, theme: str | None = None):
91
+ """Update the theme."""
92
+ if theme is None:
93
+ qapp = QApplication.instance()
94
+ if hasattr(qapp, "theme"):
95
+ theme = qapp.theme.theme
96
+ else:
97
+ theme = "dark"
98
+ self.apply_theme(theme)
99
+
100
+ def apply_theme(self, theme: str):
101
+ """Apply the theme to the plot."""
102
+ if theme == "dark":
103
+ text_color = "w"
104
+ label_bg_color = (50, 50, 50, 150)
105
+ elif theme == "light":
106
+ text_color = "k"
107
+ label_bg_color = (240, 240, 240, 150)
108
+ else:
109
+ text_color = "w"
110
+ label_bg_color = (50, 50, 50, 150)
111
+
112
+ self.coord_label.setColor(text_color)
113
+ self.coord_label.fill = pg.mkBrush(label_bg_color)
114
+ self.coord_label.border = pg.mkPen(None)
65
115
 
66
116
  def update_markers(self):
67
117
  """Update the markers for the crosshair, creating new ones if necessary."""
@@ -151,21 +201,34 @@ class Crosshair(QObject):
151
201
 
152
202
  return None, None
153
203
 
154
- def closest_x_y_value(self, input_value: float, list_x: list, list_y: list) -> tuple:
204
+ def closest_x_y_value(self, input_x: float, list_x: list, list_y: list) -> tuple:
155
205
  """
156
206
  Find the closest x and y value to the input value.
157
207
 
158
208
  Args:
159
- input_value (float): Input value
209
+ input_x (float): Input value
160
210
  list_x (list): List of x values
161
211
  list_y (list): List of y values
162
212
 
163
213
  Returns:
164
214
  tuple: Closest x and y value
165
215
  """
166
- arr = np.asarray(list_x)
167
- i = (np.abs(arr - input_value)).argmin()
168
- return list_x[i], list_y[i]
216
+ # Convert lists to NumPy arrays
217
+ arr_x = np.asarray(list_x)
218
+
219
+ # Get the indices where x is not NaN
220
+ valid_indices = ~np.isnan(arr_x)
221
+
222
+ # Filter x array to exclude NaN values
223
+ filtered_x = arr_x[valid_indices]
224
+
225
+ # Find the index of the closest value in the filtered x array
226
+ closest_index = np.abs(filtered_x - input_x).argmin()
227
+
228
+ # Map back to the original index in the list_x and list_y arrays
229
+ original_index = np.where(valid_indices)[0][closest_index]
230
+
231
+ return list_x[original_index], list_y[original_index]
169
232
 
170
233
  def mouse_moved(self, event):
171
234
  """Handles the mouse moved event, updating the crosshair position and emitting signals.
@@ -175,17 +238,15 @@ class Crosshair(QObject):
175
238
  """
176
239
  pos = event[0]
177
240
  self.update_markers()
178
- self.positionChanged.emit((pos.x(), pos.y()))
179
241
  if self.plot_item.vb.sceneBoundingRect().contains(pos):
180
242
  mouse_point = self.plot_item.vb.mapSceneToView(pos)
181
- self.v_line.setPos(mouse_point.x())
182
- self.h_line.setPos(mouse_point.y())
183
-
184
243
  x, y = mouse_point.x(), mouse_point.y()
185
- if self.is_log_x:
186
- x = 10**x
187
- if self.is_log_y:
188
- y = 10**y
244
+ self.v_line.setPos(x)
245
+ self.h_line.setPos(y)
246
+ scaled_x, scaled_y = self.scale_emitted_coordinates(mouse_point.x(), mouse_point.y())
247
+ self.crosshairChanged.emit((scaled_x, scaled_y))
248
+ self.positionChanged.emit((x, y))
249
+
189
250
  x_snap_values, y_snap_values = self.snap_to_data(x, y)
190
251
  if x_snap_values is None or y_snap_values is None:
191
252
  return
@@ -202,7 +263,12 @@ class Crosshair(QObject):
202
263
  if x is None or y is None:
203
264
  continue
204
265
  self.marker_moved_1d[name].setData([x], [y])
205
- coordinate_to_emit = (name, round(x, self.precision), round(y, self.precision))
266
+ x_snapped_scaled, y_snapped_scaled = self.scale_emitted_coordinates(x, y)
267
+ coordinate_to_emit = (
268
+ name,
269
+ round(x_snapped_scaled, self.precision),
270
+ round(y_snapped_scaled, self.precision),
271
+ )
206
272
  self.coordinatesChanged1D.emit(coordinate_to_emit)
207
273
  elif isinstance(item, pg.ImageItem):
208
274
  name = item.config.monitor
@@ -229,12 +295,10 @@ class Crosshair(QObject):
229
295
  if self.plot_item.vb.sceneBoundingRect().contains(event._scenePos):
230
296
  mouse_point = self.plot_item.vb.mapSceneToView(event._scenePos)
231
297
  x, y = mouse_point.x(), mouse_point.y()
298
+ scaled_x, scaled_y = self.scale_emitted_coordinates(mouse_point.x(), mouse_point.y())
299
+ self.crosshairClicked.emit((scaled_x, scaled_y))
232
300
  self.positionClicked.emit((x, y))
233
301
 
234
- if self.is_log_x:
235
- x = 10**x
236
- if self.is_log_y:
237
- y = 10**y
238
302
  x_snap_values, y_snap_values = self.snap_to_data(x, y)
239
303
 
240
304
  if x_snap_values is None or y_snap_values is None:
@@ -252,7 +316,12 @@ class Crosshair(QObject):
252
316
  if x is None or y is None:
253
317
  continue
254
318
  self.marker_clicked_1d[name].setData([x], [y])
255
- coordinate_to_emit = (name, round(x, self.precision), round(y, self.precision))
319
+ x_snapped_scaled, y_snapped_scaled = self.scale_emitted_coordinates(x, y)
320
+ coordinate_to_emit = (
321
+ name,
322
+ round(x_snapped_scaled, self.precision),
323
+ round(y_snapped_scaled, self.precision),
324
+ )
256
325
  self.coordinatesClicked1D.emit(coordinate_to_emit)
257
326
  elif isinstance(item, pg.ImageItem):
258
327
  name = item.config.monitor
@@ -272,10 +341,40 @@ class Crosshair(QObject):
272
341
  for marker in self.marker_clicked_1d.values():
273
342
  marker.clear()
274
343
 
344
+ def scale_emitted_coordinates(self, x, y):
345
+ """Scales the emitted coordinates if the axes are in log scale.
346
+
347
+ Args:
348
+ x (float): The x-coordinate
349
+ y (float): The y-coordinate
350
+
351
+ Returns:
352
+ tuple: The scaled x and y coordinates
353
+ """
354
+ if self.is_log_x:
355
+ x = 10**x
356
+ if self.is_log_y:
357
+ y = 10**y
358
+ return x, y
359
+
360
+ def update_coord_label(self, pos: tuple):
361
+ """Updates the coordinate label based on the crosshair position and axis scales.
362
+
363
+ Args:
364
+ pos (tuple): The (x, y) position of the crosshair.
365
+ """
366
+ x, y = pos
367
+ x_scaled, y_scaled = self.scale_emitted_coordinates(x, y)
368
+
369
+ # # Update coordinate label
370
+ self.coord_label.setText(f"({x_scaled:.{self.precision}g}, {y_scaled:.{self.precision}g})")
371
+ self.coord_label.setPos(x, y)
372
+ self.coord_label.setVisible(True)
373
+
275
374
  def check_log(self):
276
375
  """Checks if the x or y axis is in log scale and updates the internal state accordingly."""
277
- self.is_log_x = self.plot_item.ctrl.logXCheck.isChecked()
278
- self.is_log_y = self.plot_item.ctrl.logYCheck.isChecked()
376
+ self.is_log_x = self.plot_item.axes["bottom"]["item"].logMode
377
+ self.is_log_y = self.plot_item.axes["left"]["item"].logMode
279
378
  self.clear_markers()
280
379
 
281
380
  def check_derivatives(self):
@@ -284,6 +383,8 @@ class Crosshair(QObject):
284
383
  self.clear_markers()
285
384
 
286
385
  def cleanup(self):
287
- self.v_line.deleteLater()
288
- self.h_line.deleteLater()
386
+ self.plot_item.removeItem(self.v_line)
387
+ self.plot_item.removeItem(self.h_line)
388
+ self.plot_item.removeItem(self.coord_label)
389
+
289
390
  self.clear_markers()
@@ -397,8 +397,8 @@ class BECPlotBase(BECConnector, pg.GraphicsLayout):
397
397
  """Hook the crosshair to all plots."""
398
398
  if self.crosshair is None:
399
399
  self.crosshair = Crosshair(self.plot_item, precision=3)
400
- self.crosshair.positionChanged.connect(self.crosshair_position_changed)
401
- self.crosshair.positionClicked.connect(self.crosshair_position_clicked)
400
+ self.crosshair.crosshairChanged.connect(self.crosshair_position_changed)
401
+ self.crosshair.crosshairClicked.connect(self.crosshair_position_clicked)
402
402
  self.crosshair.coordinatesChanged1D.connect(self.crosshair_coordinates_changed)
403
403
  self.crosshair.coordinatesClicked1D.connect(self.crosshair_coordinates_clicked)
404
404
  self.crosshair.coordinatesChanged2D.connect(self.crosshair_coordinates_changed)
@@ -407,8 +407,8 @@ class BECPlotBase(BECConnector, pg.GraphicsLayout):
407
407
  def unhook_crosshair(self) -> None:
408
408
  """Unhook the crosshair from all plots."""
409
409
  if self.crosshair is not None:
410
- self.crosshair.positionChanged.disconnect(self.crosshair_position_changed)
411
- self.crosshair.positionClicked.disconnect(self.crosshair_position_clicked)
410
+ self.crosshair.crosshairChanged.disconnect(self.crosshair_position_changed)
411
+ self.crosshair.crosshairClicked.disconnect(self.crosshair_position_clicked)
412
412
  self.crosshair.coordinatesChanged1D.disconnect(self.crosshair_coordinates_changed)
413
413
  self.crosshair.coordinatesClicked1D.disconnect(self.crosshair_coordinates_clicked)
414
414
  self.crosshair.coordinatesChanged2D.disconnect(self.crosshair_coordinates_changed)
@@ -240,11 +240,18 @@ class PositionerBox(BECWidget, CompactPopupWidget):
240
240
  signal = hinted_signals[0]
241
241
  readback_val = signals.get(signal, {}).get("value")
242
242
 
243
- if f"{self.device}_setpoint" in signals:
244
- setpoint_val = signals.get(f"{self.device}_setpoint", {}).get("value")
245
-
246
- if f"{self.device}_motor_is_moving" in signals:
247
- is_moving = signals.get(f"{self.device}_motor_is_moving", {}).get("value")
243
+ for setpoint_signal in ["setpoint", "user_setpoint"]:
244
+ setpoint_val = signals.get(f"{self.device}_{setpoint_signal}", {}).get("value")
245
+ if setpoint_val is not None:
246
+ break
247
+
248
+ for moving_signal in ["motor_done_move", "motor_is_moving"]:
249
+ is_moving = signals.get(f"{self.device}_{moving_signal}", {}).get("value")
250
+ if is_moving is not None:
251
+ break
252
+
253
+ if is_moving is not None:
254
+ self.ui.spinner_widget.setVisible(True)
248
255
  if is_moving:
249
256
  self.ui.spinner_widget.start()
250
257
  self.ui.spinner_widget.setToolTip("Device is moving")
@@ -253,6 +260,8 @@ class PositionerBox(BECWidget, CompactPopupWidget):
253
260
  self.ui.spinner_widget.stop()
254
261
  self.ui.spinner_widget.setToolTip("Device is idle")
255
262
  self.set_global_state("success")
263
+ else:
264
+ self.ui.spinner_widget.setVisible(False)
256
265
 
257
266
  if readback_val is not None:
258
267
  self.ui.readback.setText(f"{readback_val:.{precision}f}")
@@ -1,10 +1,9 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bec_widgets
3
- Version: 1.3.3
3
+ Version: 1.4.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
7
- License-File: LICENSE
8
7
  Classifier: Development Status :: 3 - Alpha
9
8
  Classifier: Programming Language :: Python :: 3
10
9
  Classifier: Topic :: Scientific/Engineering
@@ -2,11 +2,11 @@
2
2
  .gitlab-ci.yml,sha256=Dc1iDjsc72UxdUtihx4uSZU0lrTQeR8hZwGx1MQBfKE,8432
3
3
  .pylintrc,sha256=eeY8YwSI74oFfq6IYIbCqnx3Vk8ZncKaatv96n_Y8Rs,18544
4
4
  .readthedocs.yaml,sha256=aSOc277LqXcsTI6lgvm_JY80lMlr69GbPKgivua2cS0,603
5
- CHANGELOG.md,sha256=cgyZRiQC6QIW3SQEQFw_RcJ15AdKkZrhH8tP4uJ66HU,7173
5
+ CHANGELOG.md,sha256=LVaOQfu4V_Meul8rS4CsPrrpJL9TURIrRTjD7EtcknI,7280
6
6
  LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
7
- PKG-INFO,sha256=_Vibdhs_bkm8kHRiCmMydb96n1FDg_WY_ntz057_j70,1332
7
+ PKG-INFO,sha256=VCuOaKEG3FgQYYxd7ooJyxL3PGE6Qe8Df2KICA5fRPA,1310
8
8
  README.md,sha256=Od69x-RS85Hph0-WwWACwal4yUd67XkEn4APEfHhHFw,2649
9
- pyproject.toml,sha256=_yIJ5UY-I9Lp8p4lOJ3zCvOMvlwxgqFKOXO9grFMLmM,2592
9
+ pyproject.toml,sha256=_U7BOvyswEj82ZaYzBg0xjqRFxN6jgfMiywjyapRISk,2592
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
@@ -62,7 +62,7 @@ bec_widgets/utils/bec_table.py,sha256=nA2b8ukSeUfquFMAxGrUVOqdrzMoDYD6O_4EYbOG2z
62
62
  bec_widgets/utils/bec_widget.py,sha256=1lrHNuvW6uOuPpr-cJBYJNbFekTsqpnQdfTo3P5tbWI,3330
63
63
  bec_widgets/utils/colors.py,sha256=zL9ieD_Bsb2ehd6tPpgfkhu1u5qrQRIE4mvoqM2iqko,16546
64
64
  bec_widgets/utils/container_utils.py,sha256=0wr3ZfuMiAFKCrQHVjxjw-Vuk8wsHdridqcjy2eY840,1531
65
- bec_widgets/utils/crosshair.py,sha256=f13tn1v_8FJ6C0WOLyDUXHaG_Nfzj4nMlLVEGqvs5Zc,11838
65
+ bec_widgets/utils/crosshair.py,sha256=6xtHKcYnX0oKYXAT2p7jDgaiyZTkALs66TSbI-onoh8,15618
66
66
  bec_widgets/utils/entry_validator.py,sha256=3skJIsUwTYicT76AMHm_M78RiWtUgyD2zb-Rxo2HdHQ,1313
67
67
  bec_widgets/utils/filter_io.py,sha256=GKO6GOTiKxTuTp_SHp5Ewou54N7wIZXgWWvlFvhbBmw,5114
68
68
  bec_widgets/utils/fps_counter.py,sha256=seuCWwiNP5q2e2OEztloa66pNb3Sygh-0lEHAcYaDfc,2612
@@ -174,7 +174,7 @@ bec_widgets/widgets/figure/figure.py,sha256=dHH27Fwr9dFBx4g6CXfDQr09LVAUi7xghxuk
174
174
  bec_widgets/widgets/figure/plots/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
175
175
  bec_widgets/widgets/figure/plots/axis_settings.py,sha256=grgrX4t4eAzccW4jj4HYtMSxy8Wgcd9N9J1aU7UHtIs,3723
176
176
  bec_widgets/widgets/figure/plots/axis_settings.ui,sha256=ye-guaRU_jhu7sHZS-9AjBjLrCtA1msOD0dszu4o9x8,11785
177
- bec_widgets/widgets/figure/plots/plot_base.py,sha256=ucpyhP_jNt37gghv1VTydBkzJaUlILvwfHFUapfN4v8,18360
177
+ bec_widgets/widgets/figure/plots/plot_base.py,sha256=oQiP4-FQuAeapf3H8T63S8fCoc44Zsnz7awl4ZdF-gA,18364
178
178
  bec_widgets/widgets/figure/plots/image/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
179
179
  bec_widgets/widgets/figure/plots/image/image.py,sha256=tTtBoAA5CRhSEMae0k8dElM-MznnhcgTg0flXIIduq0,28052
180
180
  bec_widgets/widgets/figure/plots/image/image_item.py,sha256=TwHo6FwCiQgJBdr-KKy_7Y_vYSB0pPjBl1AubuZSrE0,11002
@@ -212,7 +212,7 @@ bec_widgets/widgets/position_indicator/position_indicator.pyproject,sha256=s0JEf
212
212
  bec_widgets/widgets/position_indicator/position_indicator_plugin.py,sha256=ehQPpwkjJ7k365i4gdwtmAmCbVmB1tvQLEo60J_ivo4,1413
213
213
  bec_widgets/widgets/position_indicator/register_position_indicator.py,sha256=OZNiMgM_80TPSAXK_0hXAkne4vUh8DGvh_OdpOiMpwI,516
214
214
  bec_widgets/widgets/positioner_box/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
215
- bec_widgets/widgets/positioner_box/positioner_box.py,sha256=Bxt7OtaT4Xh8vuwOH3EYCsT_PwgJeFTn3Bhij8HlCR8,12097
215
+ bec_widgets/widgets/positioner_box/positioner_box.py,sha256=MK4JOBSKLCHtuM4SUw-q1R7XBwbTAfRCerhoqVv8Y7w,12409
216
216
  bec_widgets/widgets/positioner_box/positioner_box.pyproject,sha256=7966pHdDseaHciaPNEKgdQgbUThSZf5wEDCeAEJh9po,32
217
217
  bec_widgets/widgets/positioner_box/positioner_box.ui,sha256=7LZlM9smIqmkvS2KAIDkBamn04mBAkXeG9T1fpKRQe8,6093
218
218
  bec_widgets/widgets/positioner_box/positioner_box_plugin.py,sha256=kJtQgRFGkJYWbZqJ7K7o0UhdsgAlODUVZL8pKJWwMhs,1413
@@ -290,8 +290,8 @@ bec_widgets/widgets/website/register_website_widget.py,sha256=LIQJpV9uqcBiPR9cEA
290
290
  bec_widgets/widgets/website/website.py,sha256=42pncCc_zI2eqeMArIurVmPUukRo5bTxa2h1Skah-io,3012
291
291
  bec_widgets/widgets/website/website_widget.pyproject,sha256=scOiV3cV1_BjbzpPzy2N8rIJL5P2qIZz8ObTJ-Uvdtg,25
292
292
  bec_widgets/widgets/website/website_widget_plugin.py,sha256=pz38_C2cZ0yvPPS02wdIPcmhFo_yiwUhflsASocAPQQ,1341
293
- bec_widgets-1.3.3.dist-info/METADATA,sha256=_Vibdhs_bkm8kHRiCmMydb96n1FDg_WY_ntz057_j70,1332
294
- bec_widgets-1.3.3.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
295
- bec_widgets-1.3.3.dist-info/entry_points.txt,sha256=dItMzmwA1wizJ1Itx15qnfJ0ZzKVYFLVJ1voxT7K7D4,214
296
- bec_widgets-1.3.3.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
297
- bec_widgets-1.3.3.dist-info/RECORD,,
293
+ bec_widgets-1.4.1.dist-info/METADATA,sha256=VCuOaKEG3FgQYYxd7ooJyxL3PGE6Qe8Df2KICA5fRPA,1310
294
+ bec_widgets-1.4.1.dist-info/WHEEL,sha256=3U_NnUcV_1B1kPkYaPzN-irRckL5VW_lytn0ytO_kRY,87
295
+ bec_widgets-1.4.1.dist-info/entry_points.txt,sha256=dItMzmwA1wizJ1Itx15qnfJ0ZzKVYFLVJ1voxT7K7D4,214
296
+ bec_widgets-1.4.1.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
297
+ bec_widgets-1.4.1.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.25.0
2
+ Generator: hatchling 1.26.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
pyproject.toml CHANGED
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "bec_widgets"
7
- version = "1.3.3"
7
+ version = "1.4.1"
8
8
  description = "BEC Widgets"
9
9
  requires-python = ">=3.10"
10
10
  classifiers = [