bec-widgets 0.115.0__py3-none-any.whl → 0.117.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- CHANGELOG.md +31 -28
- PKG-INFO +2 -2
- bec_widgets/applications/alignment/alignment_1d/alignment_1d.ui +96 -42
- bec_widgets/cli/client.py +45 -0
- bec_widgets/qt_utils/compact_popup.py +223 -0
- bec_widgets/utils/fps_counter.py +84 -0
- bec_widgets/widgets/bec_queue/bec_queue.py +22 -7
- bec_widgets/widgets/bec_status_box/bec_status_box.py +11 -7
- bec_widgets/widgets/figure/plots/image/image.py +1 -0
- bec_widgets/widgets/figure/plots/image/image_item.py +2 -2
- bec_widgets/widgets/figure/plots/plot_base.py +62 -3
- bec_widgets/widgets/figure/plots/waveform/waveform.py +1 -0
- bec_widgets/widgets/image/image_widget.py +17 -0
- bec_widgets/widgets/waveform/waveform_widget.py +23 -3
- {bec_widgets-0.115.0.dist-info → bec_widgets-0.117.0.dist-info}/METADATA +2 -2
- {bec_widgets-0.115.0.dist-info → bec_widgets-0.117.0.dist-info}/RECORD +20 -18
- pyproject.toml +2 -2
- {bec_widgets-0.115.0.dist-info → bec_widgets-0.117.0.dist-info}/WHEEL +0 -0
- {bec_widgets-0.115.0.dist-info → bec_widgets-0.117.0.dist-info}/entry_points.txt +0 -0
- {bec_widgets-0.115.0.dist-info → bec_widgets-0.117.0.dist-info}/licenses/LICENSE +0 -0
CHANGELOG.md
CHANGED
@@ -1,6 +1,37 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
3
|
|
4
|
+
## v0.117.0 (2024-10-11)
|
5
|
+
|
6
|
+
### Features
|
7
|
+
|
8
|
+
* 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))
|
9
|
+
|
10
|
+
### Unknown
|
11
|
+
|
12
|
+
* tests(plot_base): tests extended ([`8dc892d`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/8dc892df0a47ccbdd812555b7c5775a455a23ede))
|
13
|
+
|
14
|
+
|
15
|
+
## v0.116.0 (2024-10-11)
|
16
|
+
|
17
|
+
### Build System
|
18
|
+
|
19
|
+
* build: fix PySide6 to 6.7.2 ([`908dbc1`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/908dbc1760da5b323722207163f00850b84fb90b))
|
20
|
+
|
21
|
+
### Features
|
22
|
+
|
23
|
+
* feat: UI changes to have top toolbar with compact popup widgets (fix issue #360) ([`499b6b9`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/499b6b9a12efd931b5728b519404c41a7e29e4d6))
|
24
|
+
|
25
|
+
* feat: adapt BECQueue and BECStatusBox widgets to use CompactPopupWidget ([`94ce92f`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/94ce92f5b054d25ea3bb7976c1f75e14b78b9edc))
|
26
|
+
|
27
|
+
* feat: add 'CompactPopupWidget' container widget
|
28
|
+
|
29
|
+
Makes it easy to write widgets which can have a compact
|
30
|
+
representation with LED-like global state indicator,
|
31
|
+
with the possibility to display a popup dialog with more
|
32
|
+
complete UI ([`49268e3`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/49268e3829406d70b09e4d88989812f5578e46f4))
|
33
|
+
|
34
|
+
|
4
35
|
## v0.115.0 (2024-10-08)
|
5
36
|
|
6
37
|
### Features
|
@@ -143,31 +174,3 @@ Fixes #361, do not try to change x axis when not permitted ([`efa2763`](https://
|
|
143
174
|
### Features
|
144
175
|
|
145
176
|
* feat(progressbar): added bec progressbar ([`f6d1d0b`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/f6d1d0bbe3ba30a3b7291cd36a1f7f8e6bd5b895))
|
146
|
-
|
147
|
-
* feat(generate_cli): added support for property and qproperty setter ([`a52182d`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/a52182dca978833bfc3fad755c596d3a2ef45c42))
|
148
|
-
|
149
|
-
|
150
|
-
## v0.107.0 (2024-09-06)
|
151
|
-
|
152
|
-
### Documentation
|
153
|
-
|
154
|
-
* docs: extend waveform docs ([`e6976dc`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/e6976dc15105209852090a00a97b7cda723142e9))
|
155
|
-
|
156
|
-
### Features
|
157
|
-
|
158
|
-
* feat: add roi select for dap, allow automatic clear curves on plot request ([`7bdca84`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/7bdca8431496fe6562d2c28f5a6af869d1a2e654))
|
159
|
-
|
160
|
-
### Refactoring
|
161
|
-
|
162
|
-
* refactor: change style to bec_accent_colors ([`bd126dd`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/bd126dddbbec3e6c448cce263433d328d577c5c0))
|
163
|
-
|
164
|
-
### Testing
|
165
|
-
|
166
|
-
* test: add tests, including extension to end-2-end test ([`b1aff6d`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/b1aff6d791ff847eb2f628e66ccaa4672fdeea08))
|
167
|
-
|
168
|
-
|
169
|
-
## v0.106.0 (2024-09-05)
|
170
|
-
|
171
|
-
### Features
|
172
|
-
|
173
|
-
* feat(plot_base): toggle to switch outer axes for plotting widgets ([`06d7741`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/06d7741622aea8556208cd17cae521c37333f8b6))
|
PKG-INFO
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: bec_widgets
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.117.0
|
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
|
@@ -32,4 +32,4 @@ Provides-Extra: pyqt6
|
|
32
32
|
Requires-Dist: pyqt6-webengine>=6.7; extra == 'pyqt6'
|
33
33
|
Requires-Dist: pyqt6>=6.7; extra == 'pyqt6'
|
34
34
|
Provides-Extra: pyside6
|
35
|
-
Requires-Dist: pyside6
|
35
|
+
Requires-Dist: pyside6~=6.7.2; extra == 'pyside6'
|
@@ -15,47 +15,65 @@
|
|
15
15
|
</property>
|
16
16
|
<layout class="QVBoxLayout" name="verticalLayout">
|
17
17
|
<item>
|
18
|
-
<layout class="QHBoxLayout" name="horizontalLayout_3" stretch="0,0,0,0,0,1">
|
18
|
+
<layout class="QHBoxLayout" name="horizontalLayout_3" stretch="0,0,0,0,0,0,0,0,0,0,1">
|
19
19
|
<item>
|
20
20
|
<widget class="DarkModeButton" name="dark_mode_button"/>
|
21
21
|
</item>
|
22
22
|
<item>
|
23
|
-
<
|
24
|
-
<property name="
|
25
|
-
<
|
26
|
-
</property>
|
27
|
-
<property name="text">
|
28
|
-
<string>BEC Server State</string>
|
23
|
+
<spacer name="horizontalSpacer_6">
|
24
|
+
<property name="orientation">
|
25
|
+
<enum>Qt::Orientation::Horizontal</enum>
|
29
26
|
</property>
|
30
|
-
<property name="
|
31
|
-
<
|
27
|
+
<property name="sizeHint" stdset="0">
|
28
|
+
<size>
|
29
|
+
<width>40</width>
|
30
|
+
<height>20</height>
|
31
|
+
</size>
|
32
32
|
</property>
|
33
|
-
|
33
|
+
</spacer>
|
34
|
+
</item>
|
35
|
+
<item>
|
36
|
+
<widget class="BECStatusBox" name="bec_status_box">
|
37
|
+
<property name="compact" stdset="0">
|
34
38
|
<bool>true</bool>
|
35
39
|
</property>
|
36
|
-
<property name="
|
37
|
-
<
|
40
|
+
<property name="label" stdset="0">
|
41
|
+
<string>BEC Servers</string>
|
38
42
|
</property>
|
39
43
|
</widget>
|
40
44
|
</item>
|
41
45
|
<item>
|
42
|
-
<
|
43
|
-
<property name="
|
44
|
-
<
|
46
|
+
<spacer name="horizontalSpacer_4">
|
47
|
+
<property name="orientation">
|
48
|
+
<enum>Qt::Orientation::Horizontal</enum>
|
45
49
|
</property>
|
46
|
-
<property name="
|
47
|
-
<
|
50
|
+
<property name="sizeHint" stdset="0">
|
51
|
+
<size>
|
52
|
+
<width>40</width>
|
53
|
+
<height>20</height>
|
54
|
+
</size>
|
48
55
|
</property>
|
49
|
-
|
56
|
+
</spacer>
|
57
|
+
</item>
|
58
|
+
<item>
|
59
|
+
<widget class="BECQueue" name="bec_queue">
|
60
|
+
<property name="compact" stdset="0">
|
50
61
|
<bool>true</bool>
|
51
62
|
</property>
|
52
|
-
|
53
|
-
|
63
|
+
</widget>
|
64
|
+
</item>
|
65
|
+
<item>
|
66
|
+
<spacer name="horizontalSpacer_3">
|
67
|
+
<property name="orientation">
|
68
|
+
<enum>Qt::Orientation::Horizontal</enum>
|
54
69
|
</property>
|
55
|
-
<property name="
|
56
|
-
<
|
70
|
+
<property name="sizeHint" stdset="0">
|
71
|
+
<size>
|
72
|
+
<width>40</width>
|
73
|
+
<height>20</height>
|
74
|
+
</size>
|
57
75
|
</property>
|
58
|
-
</
|
76
|
+
</spacer>
|
59
77
|
</item>
|
60
78
|
<item>
|
61
79
|
<widget class="QRadioButton" name="radioButton">
|
@@ -76,6 +94,19 @@
|
|
76
94
|
</property>
|
77
95
|
</widget>
|
78
96
|
</item>
|
97
|
+
<item>
|
98
|
+
<spacer name="horizontalSpacer_5">
|
99
|
+
<property name="orientation">
|
100
|
+
<enum>Qt::Orientation::Horizontal</enum>
|
101
|
+
</property>
|
102
|
+
<property name="sizeHint" stdset="0">
|
103
|
+
<size>
|
104
|
+
<width>40</width>
|
105
|
+
<height>20</height>
|
106
|
+
</size>
|
107
|
+
</property>
|
108
|
+
</spacer>
|
109
|
+
</item>
|
79
110
|
<item>
|
80
111
|
<widget class="QRadioButton" name="radioButton_3">
|
81
112
|
<property name="enabled">
|
@@ -95,6 +126,19 @@
|
|
95
126
|
</property>
|
96
127
|
</widget>
|
97
128
|
</item>
|
129
|
+
<item>
|
130
|
+
<spacer name="horizontalSpacer_7">
|
131
|
+
<property name="orientation">
|
132
|
+
<enum>Qt::Orientation::Horizontal</enum>
|
133
|
+
</property>
|
134
|
+
<property name="sizeHint" stdset="0">
|
135
|
+
<size>
|
136
|
+
<width>40</width>
|
137
|
+
<height>20</height>
|
138
|
+
</size>
|
139
|
+
</property>
|
140
|
+
</spacer>
|
141
|
+
</item>
|
98
142
|
<item>
|
99
143
|
<widget class="StopButton" name="stop_button">
|
100
144
|
<property name="sizePolicy">
|
@@ -652,14 +696,19 @@
|
|
652
696
|
</widget>
|
653
697
|
<customwidgets>
|
654
698
|
<customwidget>
|
655
|
-
<class>
|
699
|
+
<class>ToggleSwitch</class>
|
656
700
|
<extends>QWidget</extends>
|
657
|
-
<header>
|
701
|
+
<header>toggle_switch</header>
|
658
702
|
</customwidget>
|
659
703
|
<customwidget>
|
660
|
-
<class>
|
704
|
+
<class>BECWaveformWidget</class>
|
661
705
|
<extends>QWidget</extends>
|
662
|
-
<header>
|
706
|
+
<header>bec_waveform_widget</header>
|
707
|
+
</customwidget>
|
708
|
+
<customwidget>
|
709
|
+
<class>BECStatusBox</class>
|
710
|
+
<extends>QWidget</extends>
|
711
|
+
<header>bec_status_box</header>
|
663
712
|
</customwidget>
|
664
713
|
<customwidget>
|
665
714
|
<class>WebsiteWidget</class>
|
@@ -667,44 +716,49 @@
|
|
667
716
|
<header>website_widget</header>
|
668
717
|
</customwidget>
|
669
718
|
<customwidget>
|
670
|
-
<class>
|
719
|
+
<class>StopButton</class>
|
671
720
|
<extends>QWidget</extends>
|
672
|
-
<header>
|
721
|
+
<header>stop_button</header>
|
673
722
|
</customwidget>
|
674
723
|
<customwidget>
|
675
|
-
<class>
|
724
|
+
<class>LMFitDialog</class>
|
676
725
|
<extends>QWidget</extends>
|
677
|
-
<header>
|
726
|
+
<header>lm_fit_dialog</header>
|
678
727
|
</customwidget>
|
679
728
|
<customwidget>
|
680
|
-
<class>
|
729
|
+
<class>ScanControl</class>
|
681
730
|
<extends>QWidget</extends>
|
682
|
-
<header>
|
731
|
+
<header>scan_control</header>
|
732
|
+
</customwidget>
|
733
|
+
<customwidget>
|
734
|
+
<class>BECQueue</class>
|
735
|
+
<extends>QWidget</extends>
|
736
|
+
<header>bec_queue</header>
|
683
737
|
</customwidget>
|
684
738
|
<customwidget>
|
685
739
|
<class>BECProgressBar</class>
|
686
740
|
<extends>QWidget</extends>
|
687
741
|
<header>bec_progress_bar</header>
|
688
742
|
</customwidget>
|
743
|
+
<customwidget>
|
744
|
+
<class>DeviceComboBox</class>
|
745
|
+
<extends>QComboBox</extends>
|
746
|
+
<header>device_combobox</header>
|
747
|
+
</customwidget>
|
689
748
|
<customwidget>
|
690
749
|
<class>DarkModeButton</class>
|
691
750
|
<extends>QWidget</extends>
|
692
751
|
<header>dark_mode_button</header>
|
693
752
|
</customwidget>
|
694
753
|
<customwidget>
|
695
|
-
<class>
|
754
|
+
<class>DapComboBox</class>
|
696
755
|
<extends>QWidget</extends>
|
697
|
-
<header>
|
698
|
-
</customwidget>
|
699
|
-
<customwidget>
|
700
|
-
<class>DeviceComboBox</class>
|
701
|
-
<extends>QComboBox</extends>
|
702
|
-
<header>device_combobox</header>
|
756
|
+
<header>dap_combo_box</header>
|
703
757
|
</customwidget>
|
704
758
|
<customwidget>
|
705
|
-
<class>
|
759
|
+
<class>PositionerBox</class>
|
706
760
|
<extends>QWidget</extends>
|
707
|
-
<header>
|
761
|
+
<header>positioner_box</header>
|
708
762
|
</customwidget>
|
709
763
|
</customwidgets>
|
710
764
|
<tabstops>
|
bec_widgets/cli/client.py
CHANGED
@@ -1135,6 +1135,15 @@ class BECImageShow(RPCBase):
|
|
1135
1135
|
y(bool): Show grid on the y-axis.
|
1136
1136
|
"""
|
1137
1137
|
|
1138
|
+
@rpc_call
|
1139
|
+
def enable_fps_monitor(self, enable: "bool" = True):
|
1140
|
+
"""
|
1141
|
+
Enable the FPS monitor.
|
1142
|
+
|
1143
|
+
Args:
|
1144
|
+
enable(bool): True to enable, False to disable.
|
1145
|
+
"""
|
1146
|
+
|
1138
1147
|
@rpc_call
|
1139
1148
|
def lock_aspect_ratio(self, lock):
|
1140
1149
|
"""
|
@@ -1330,6 +1339,15 @@ class BECImageWidget(RPCBase):
|
|
1330
1339
|
y_grid(bool): Visibility of the y-axis grid.
|
1331
1340
|
"""
|
1332
1341
|
|
1342
|
+
@rpc_call
|
1343
|
+
def enable_fps_monitor(self, enabled: "bool"):
|
1344
|
+
"""
|
1345
|
+
Enable the FPS monitor of the plot widget.
|
1346
|
+
|
1347
|
+
Args:
|
1348
|
+
enabled(bool): If True, enable the FPS monitor.
|
1349
|
+
"""
|
1350
|
+
|
1333
1351
|
@rpc_call
|
1334
1352
|
def lock_aspect_ratio(self, lock: "bool"):
|
1335
1353
|
"""
|
@@ -1666,6 +1684,15 @@ class BECPlotBase(RPCBase):
|
|
1666
1684
|
show(bool): Show the outer axes.
|
1667
1685
|
"""
|
1668
1686
|
|
1687
|
+
@rpc_call
|
1688
|
+
def enable_fps_monitor(self, enable: "bool" = True):
|
1689
|
+
"""
|
1690
|
+
Enable the FPS monitor.
|
1691
|
+
|
1692
|
+
Args:
|
1693
|
+
enable(bool): True to enable, False to disable.
|
1694
|
+
"""
|
1695
|
+
|
1669
1696
|
@rpc_call
|
1670
1697
|
def lock_aspect_ratio(self, lock):
|
1671
1698
|
"""
|
@@ -2069,6 +2096,15 @@ class BECWaveform(RPCBase):
|
|
2069
2096
|
colormap(str, optional): Scale the colors of curves to colormap. If None, use the default color palette.
|
2070
2097
|
"""
|
2071
2098
|
|
2099
|
+
@rpc_call
|
2100
|
+
def enable_fps_monitor(self, enable: "bool" = True):
|
2101
|
+
"""
|
2102
|
+
Enable the FPS monitor.
|
2103
|
+
|
2104
|
+
Args:
|
2105
|
+
enable(bool): True to enable, False to disable.
|
2106
|
+
"""
|
2107
|
+
|
2072
2108
|
@rpc_call
|
2073
2109
|
def lock_aspect_ratio(self, lock):
|
2074
2110
|
"""
|
@@ -2374,6 +2410,15 @@ class BECWaveformWidget(RPCBase):
|
|
2374
2410
|
y_grid(bool): Visibility of the y-axis grid.
|
2375
2411
|
"""
|
2376
2412
|
|
2413
|
+
@rpc_call
|
2414
|
+
def enable_fps_monitor(self, enabled: "bool"):
|
2415
|
+
"""
|
2416
|
+
Enable the FPS monitor of the plot widget.
|
2417
|
+
|
2418
|
+
Args:
|
2419
|
+
enabled(bool): If True, enable the FPS monitor.
|
2420
|
+
"""
|
2421
|
+
|
2377
2422
|
@rpc_call
|
2378
2423
|
def lock_aspect_ratio(self, lock: "bool"):
|
2379
2424
|
"""
|
@@ -0,0 +1,223 @@
|
|
1
|
+
from types import SimpleNamespace
|
2
|
+
|
3
|
+
from bec_qthemes import material_icon
|
4
|
+
from qtpy.QtCore import Property, Qt
|
5
|
+
from qtpy.QtGui import QColor
|
6
|
+
from qtpy.QtWidgets import (
|
7
|
+
QDialog,
|
8
|
+
QHBoxLayout,
|
9
|
+
QLabel,
|
10
|
+
QPushButton,
|
11
|
+
QSizePolicy,
|
12
|
+
QVBoxLayout,
|
13
|
+
QWidget,
|
14
|
+
)
|
15
|
+
|
16
|
+
from bec_widgets.utils.colors import get_accent_colors
|
17
|
+
|
18
|
+
|
19
|
+
class LedLabel(QLabel):
|
20
|
+
success_led = "color: white;border-radius: 10;background-color: qlineargradient(spread:pad, x1:0.145, y1:0.16, x2:1, y2:1, stop:0 %s, stop:1 %s);"
|
21
|
+
emergency_led = "color: white;border-radius: 10;background-color: qlineargradient(spread:pad, x1:0.145, y1:0.16, x2:0.92, y2:0.988636, stop:0 %s, stop:1 %s);"
|
22
|
+
warning_led = "color: white;border-radius: 10;background-color: qlineargradient(spread:pad, x1:0.232, y1:0.272, x2:0.98, y2:0.959773, stop:0 %s, stop:1 %s);"
|
23
|
+
default_led = "color: white;border-radius: 10;background-color: qlineargradient(spread:pad, x1:0.04, y1:0.0565909, x2:0.799, y2:0.795, stop:0 %s, stop:1 %s);"
|
24
|
+
|
25
|
+
def __init__(self, parent=None):
|
26
|
+
super().__init__(parent)
|
27
|
+
|
28
|
+
self.palette = get_accent_colors()
|
29
|
+
if self.palette is None:
|
30
|
+
# no theme!
|
31
|
+
self.palette = SimpleNamespace(
|
32
|
+
default=QColor("blue"),
|
33
|
+
success=QColor("green"),
|
34
|
+
warning=QColor("orange"),
|
35
|
+
emergency=QColor("red"),
|
36
|
+
)
|
37
|
+
self.setState("default")
|
38
|
+
self.setFixedSize(20, 20)
|
39
|
+
|
40
|
+
def setState(self, state: str):
|
41
|
+
match state:
|
42
|
+
case "success":
|
43
|
+
r, g, b, a = self.palette.success.getRgb()
|
44
|
+
self.setStyleSheet(
|
45
|
+
LedLabel.success_led
|
46
|
+
% (
|
47
|
+
f"rgba({r},{g},{b},{a})",
|
48
|
+
f"rgba({int(r*0.8)},{int(g*0.8)},{int(b*0.8)},{a})",
|
49
|
+
)
|
50
|
+
)
|
51
|
+
case "default":
|
52
|
+
r, g, b, a = self.palette.default.getRgb()
|
53
|
+
self.setStyleSheet(
|
54
|
+
LedLabel.default_led
|
55
|
+
% (
|
56
|
+
f"rgba({r},{g},{b},{a})",
|
57
|
+
f"rgba({int(r*0.8)},{int(g*0.8)},{int(b*0.8)},{a})",
|
58
|
+
)
|
59
|
+
)
|
60
|
+
case "warning":
|
61
|
+
r, g, b, a = self.palette.warning.getRgb()
|
62
|
+
self.setStyleSheet(
|
63
|
+
LedLabel.warning_led
|
64
|
+
% (
|
65
|
+
f"rgba({r},{g},{b},{a})",
|
66
|
+
f"rgba({int(r*0.8)},{int(g*0.8)},{int(b*0.8)},{a})",
|
67
|
+
)
|
68
|
+
)
|
69
|
+
case "emergency":
|
70
|
+
r, g, b, a = self.palette.emergency.getRgb()
|
71
|
+
self.setStyleSheet(
|
72
|
+
LedLabel.emergency_led
|
73
|
+
% (
|
74
|
+
f"rgba({r},{g},{b},{a})",
|
75
|
+
f"rgba({int(r*0.8)},{int(g*0.8)},{int(b*0.8)},{a})",
|
76
|
+
)
|
77
|
+
)
|
78
|
+
case unknown_state:
|
79
|
+
raise ValueError(
|
80
|
+
f"Unknown state {repr(unknown_state)}, must be one of default, success, warning or emergency"
|
81
|
+
)
|
82
|
+
|
83
|
+
|
84
|
+
class PopupDialog(QDialog):
|
85
|
+
def __init__(self, content_widget):
|
86
|
+
self.parent = content_widget.parent()
|
87
|
+
self.content_widget = content_widget
|
88
|
+
|
89
|
+
super().__init__(self.parent)
|
90
|
+
|
91
|
+
self.setAttribute(Qt.WA_DeleteOnClose)
|
92
|
+
|
93
|
+
self.content_widget.setParent(self)
|
94
|
+
QVBoxLayout(self)
|
95
|
+
self.layout().addWidget(self.content_widget)
|
96
|
+
self.content_widget.setVisible(True)
|
97
|
+
|
98
|
+
def closeEvent(self, event):
|
99
|
+
self.content_widget.setVisible(False)
|
100
|
+
self.content_widget.setParent(self.parent)
|
101
|
+
|
102
|
+
|
103
|
+
class CompactPopupWidget(QWidget):
|
104
|
+
"""Container widget, that can display its content or have a compact form,
|
105
|
+
in this case clicking on a small button pops the contained widget up.
|
106
|
+
|
107
|
+
In the compact form, a LED-like indicator shows a status indicator.
|
108
|
+
"""
|
109
|
+
|
110
|
+
def __init__(self, parent=None, layout=QVBoxLayout):
|
111
|
+
super().__init__(parent)
|
112
|
+
|
113
|
+
self._popup_window = None
|
114
|
+
|
115
|
+
QVBoxLayout(self)
|
116
|
+
self.compact_view = QWidget(self)
|
117
|
+
self.compact_view.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
|
118
|
+
QHBoxLayout(self.compact_view)
|
119
|
+
self.compact_view.layout().setSpacing(0)
|
120
|
+
self.compact_view.layout().setContentsMargins(0, 0, 0, 0)
|
121
|
+
self.compact_label = QLabel(self.compact_view)
|
122
|
+
self.compact_status = LedLabel(self.compact_view)
|
123
|
+
self.compact_show_popup = QPushButton(self.compact_view)
|
124
|
+
self.compact_show_popup.setFlat(True)
|
125
|
+
self.compact_show_popup.setIcon(
|
126
|
+
material_icon(icon_name="pan_zoom", size=(10, 10), convert_to_pixmap=False)
|
127
|
+
)
|
128
|
+
self.compact_view.layout().addWidget(self.compact_label)
|
129
|
+
self.compact_view.layout().addWidget(self.compact_status)
|
130
|
+
self.compact_view.layout().addWidget(self.compact_show_popup)
|
131
|
+
self.compact_view.setVisible(False)
|
132
|
+
self.layout().addWidget(self.compact_view)
|
133
|
+
self.container = QWidget(self)
|
134
|
+
self.layout().addWidget(self.container)
|
135
|
+
self.container.setVisible(True)
|
136
|
+
layout(self.container)
|
137
|
+
self.layout = self.container.layout()
|
138
|
+
|
139
|
+
self.compact_show_popup.clicked.connect(self.show_popup)
|
140
|
+
|
141
|
+
def set_global_state(self, state: str):
|
142
|
+
"""Set the LED-indicator state
|
143
|
+
|
144
|
+
The LED indicator represents the 'global' state. State can be one of the
|
145
|
+
following: "default", "success", "warning", "emergency"
|
146
|
+
"""
|
147
|
+
self.compact_status.setState(state)
|
148
|
+
|
149
|
+
def show_popup(self):
|
150
|
+
"""Display the contained widgets in a popup dialog"""
|
151
|
+
self._popup_window = PopupDialog(self.container)
|
152
|
+
self._popup_window.show()
|
153
|
+
|
154
|
+
def setSizePolicy(self, size_policy1, size_policy2=None):
|
155
|
+
# setting size policy on the compact popup widget will set
|
156
|
+
# the policy for the container, and for itself
|
157
|
+
if size_policy2 is None:
|
158
|
+
# assuming first form: setSizePolicy(QSizePolicy)
|
159
|
+
self.container.setSizePolicy(size_policy1)
|
160
|
+
QWidget.setSizePolicy(self, size_policy1)
|
161
|
+
else:
|
162
|
+
self.container.setSizePolicy(size_policy1, size_policy2)
|
163
|
+
QWidget.setSizePolicy(self, size_policy1, size_policy2)
|
164
|
+
|
165
|
+
def addWidget(self, widget):
|
166
|
+
"""Add a widget to the popup container
|
167
|
+
|
168
|
+
The popup container corresponds to the "full view" (not compact)
|
169
|
+
The widget is reparented to the container, and added to the container layout
|
170
|
+
"""
|
171
|
+
widget.setParent(self.container)
|
172
|
+
self.container.layout().addWidget(widget)
|
173
|
+
|
174
|
+
@Property(bool)
|
175
|
+
def compact(self):
|
176
|
+
return self.compact_view.isVisible()
|
177
|
+
|
178
|
+
@compact.setter
|
179
|
+
def compact(self, set_compact: bool):
|
180
|
+
"""Sets the compact form
|
181
|
+
|
182
|
+
If set_compact is True, the compact view is displayed ; otherwise,
|
183
|
+
the full view is displayed. This is handled by toggling visibility of
|
184
|
+
the container widget or the compact view widget.
|
185
|
+
"""
|
186
|
+
if set_compact:
|
187
|
+
self.compact_view.setVisible(True)
|
188
|
+
self.container.setVisible(False)
|
189
|
+
QWidget.setSizePolicy(self, QSizePolicy.Fixed, QSizePolicy.Fixed)
|
190
|
+
else:
|
191
|
+
self.compact_view.setVisible(False)
|
192
|
+
self.container.setVisible(True)
|
193
|
+
QWidget.setSizePolicy(self, self.container.sizePolicy())
|
194
|
+
if self.parentWidget():
|
195
|
+
self.parentWidget().adjustSize()
|
196
|
+
else:
|
197
|
+
self.adjustSize()
|
198
|
+
|
199
|
+
@Property(str)
|
200
|
+
def label(self):
|
201
|
+
return self.compact_label.text()
|
202
|
+
|
203
|
+
@label.setter
|
204
|
+
def label(self, compact_label_text: str):
|
205
|
+
"""Set the label text associated to the compact view"""
|
206
|
+
self.compact_label.setText(compact_label_text)
|
207
|
+
|
208
|
+
@Property(str)
|
209
|
+
def tooltip(self):
|
210
|
+
return self.compact_label.toolTip()
|
211
|
+
|
212
|
+
@tooltip.setter
|
213
|
+
def tooltip(self, tooltip: str):
|
214
|
+
"""Set the tooltip text associated to the compact view"""
|
215
|
+
self.compact_label.setToolTip(tooltip)
|
216
|
+
self.compact_status.setToolTip(tooltip)
|
217
|
+
|
218
|
+
def closeEvent(self, event):
|
219
|
+
# Called by Qt, on closing - since the children widgets can be
|
220
|
+
# BECWidgets, it is good to explicitely call 'close' on them,
|
221
|
+
# to ensure proper resources cleanup
|
222
|
+
for child in self.container.findChildren(QWidget, options=Qt.FindDirectChildrenOnly):
|
223
|
+
child.close()
|
@@ -0,0 +1,84 @@
|
|
1
|
+
"""
|
2
|
+
This module provides a utility class for counting and reporting frames per second (FPS) in a PyQtGraph application.
|
3
|
+
|
4
|
+
Classes:
|
5
|
+
FPSCounter: A class that monitors the paint events of a `ViewBox` to calculate and emit FPS values.
|
6
|
+
|
7
|
+
Usage:
|
8
|
+
The `FPSCounter` class can be used to monitor the rendering performance of a `ViewBox` in a PyQtGraph application.
|
9
|
+
It connects to the `ViewBox`'s paint event and calculates the FPS over a specified interval, emitting the FPS value
|
10
|
+
at regular intervals.
|
11
|
+
|
12
|
+
Example:
|
13
|
+
from qtpy import QtWidgets, QtCore
|
14
|
+
import pyqtgraph as pg
|
15
|
+
from fps_counter import FPSCounter
|
16
|
+
|
17
|
+
app = pg.mkQApp("FPS Counter Example")
|
18
|
+
win = pg.GraphicsLayoutWidget()
|
19
|
+
win.show()
|
20
|
+
|
21
|
+
vb = pg.ViewBox()
|
22
|
+
plot_item = pg.PlotItem(viewBox=vb)
|
23
|
+
win.addItem(plot_item)
|
24
|
+
|
25
|
+
fps_counter = FPSCounter(vb)
|
26
|
+
fps_counter.sigFpsUpdate.connect(lambda fps: print(f"FPS: {fps:.2f}"))
|
27
|
+
|
28
|
+
sys.exit(app.exec_())
|
29
|
+
"""
|
30
|
+
|
31
|
+
from time import perf_counter
|
32
|
+
|
33
|
+
import pyqtgraph as pg
|
34
|
+
from qtpy import QtCore
|
35
|
+
|
36
|
+
|
37
|
+
class FPSCounter(QtCore.QObject):
|
38
|
+
"""
|
39
|
+
A utility class for counting and reporting frames per second (FPS).
|
40
|
+
|
41
|
+
This class connects to a `ViewBox`'s paint event to count the number of
|
42
|
+
frames rendered and calculates the FPS over a specified interval. It emits
|
43
|
+
a signal with the FPS value at regular intervals.
|
44
|
+
|
45
|
+
Attributes:
|
46
|
+
sigFpsUpdate (QtCore.Signal): Signal emitted with the FPS value.
|
47
|
+
view_box (pg.ViewBox): The `ViewBox` instance to monitor.
|
48
|
+
"""
|
49
|
+
|
50
|
+
sigFpsUpdate = QtCore.Signal(float)
|
51
|
+
|
52
|
+
def __init__(self, view_box):
|
53
|
+
super().__init__()
|
54
|
+
self.view_box = view_box
|
55
|
+
self.view_box.sigPaint.connect(self.increment_count)
|
56
|
+
self.count = 0
|
57
|
+
self.last_update = perf_counter()
|
58
|
+
self.timer = QtCore.QTimer()
|
59
|
+
self.timer.timeout.connect(self.calculate_fps)
|
60
|
+
self.timer.start(1000)
|
61
|
+
|
62
|
+
def increment_count(self):
|
63
|
+
"""
|
64
|
+
Increment the frame count when the `ViewBox` is painted.
|
65
|
+
"""
|
66
|
+
self.count += 1
|
67
|
+
|
68
|
+
def calculate_fps(self):
|
69
|
+
"""
|
70
|
+
Calculate the frames per second (FPS) based on the number of frames
|
71
|
+
"""
|
72
|
+
now = perf_counter()
|
73
|
+
elapsed = now - self.last_update
|
74
|
+
fps = self.count / elapsed if elapsed > 0 else 0.0
|
75
|
+
self.last_update = now
|
76
|
+
self.count = 0
|
77
|
+
self.sigFpsUpdate.emit(fps)
|
78
|
+
|
79
|
+
def cleanup(self):
|
80
|
+
"""
|
81
|
+
Clean up the FPS counter by stopping the timer and disconnecting the signal.
|
82
|
+
"""
|
83
|
+
self.timer.stop()
|
84
|
+
self.timer.timeout.disconnect(self.calculate_fps)
|
@@ -2,10 +2,11 @@ from __future__ import annotations
|
|
2
2
|
|
3
3
|
from bec_lib.endpoints import MessageEndpoints
|
4
4
|
from bec_qthemes import material_icon
|
5
|
-
from qtpy.QtCore import Property, Qt, Slot
|
5
|
+
from qtpy.QtCore import Property, Qt, Signal, Slot
|
6
6
|
from qtpy.QtGui import QColor
|
7
7
|
from qtpy.QtWidgets import QHeaderView, QLabel, QTableWidget, QTableWidgetItem, QVBoxLayout, QWidget
|
8
8
|
|
9
|
+
from bec_widgets.qt_utils.compact_popup import CompactPopupWidget
|
9
10
|
from bec_widgets.qt_utils.toolbar import ModularToolBar, SeparatorAction, WidgetAction
|
10
11
|
from bec_widgets.utils.bec_connector import ConnectionConfig
|
11
12
|
from bec_widgets.utils.bec_widget import BECWidget
|
@@ -15,7 +16,7 @@ from bec_widgets.widgets.button_resume.button_resume import ResumeButton
|
|
15
16
|
from bec_widgets.widgets.stop_button.stop_button import StopButton
|
16
17
|
|
17
18
|
|
18
|
-
class BECQueue(BECWidget,
|
19
|
+
class BECQueue(BECWidget, CompactPopupWidget):
|
19
20
|
"""
|
20
21
|
Widget to display the BEC queue.
|
21
22
|
"""
|
@@ -31,6 +32,8 @@ class BECQueue(BECWidget, QWidget):
|
|
31
32
|
"COMPLETED": "blue",
|
32
33
|
}
|
33
34
|
|
35
|
+
queue_busy = Signal(bool)
|
36
|
+
|
34
37
|
def __init__(
|
35
38
|
self,
|
36
39
|
parent: QWidget | None = None,
|
@@ -40,22 +43,24 @@ class BECQueue(BECWidget, QWidget):
|
|
40
43
|
refresh_upon_start: bool = True,
|
41
44
|
):
|
42
45
|
super().__init__(client, config, gui_id)
|
43
|
-
|
44
|
-
self.layout = QVBoxLayout(self)
|
46
|
+
CompactPopupWidget.__init__(self, parent=parent, layout=QVBoxLayout)
|
45
47
|
self.layout.setSpacing(0)
|
46
48
|
self.layout.setContentsMargins(0, 0, 0, 0)
|
47
49
|
|
48
50
|
# Set up the toolbar
|
49
51
|
self.set_toolbar()
|
50
|
-
|
51
52
|
# Set up the table
|
52
53
|
self.table = QTableWidget(self)
|
53
|
-
self.layout.addWidget(self.table)
|
54
|
+
# self.layout.addWidget(self.table)
|
54
55
|
self.table.setColumnCount(4)
|
55
56
|
self.table.setHorizontalHeaderLabels(["Scan Number", "Type", "Status", "Cancel"])
|
56
57
|
header = self.table.horizontalHeader()
|
57
58
|
header.setSectionResizeMode(QHeaderView.Stretch)
|
58
59
|
|
60
|
+
self.addWidget(self.table)
|
61
|
+
self.label = "BEC Queue"
|
62
|
+
self.tooltip = "BEC Queue status"
|
63
|
+
|
59
64
|
self.bec_dispatcher.connect_slot(self.update_queue, MessageEndpoints.scan_queue_status())
|
60
65
|
self.reset_content()
|
61
66
|
if refresh_upon_start:
|
@@ -78,7 +83,7 @@ class BECQueue(BECWidget, QWidget):
|
|
78
83
|
target_widget=self,
|
79
84
|
)
|
80
85
|
|
81
|
-
self.
|
86
|
+
self.addWidget(self.toolbar)
|
82
87
|
|
83
88
|
@Property(bool)
|
84
89
|
def hide_toolbar(self):
|
@@ -109,6 +114,9 @@ class BECQueue(BECWidget, QWidget):
|
|
109
114
|
Refresh the queue.
|
110
115
|
"""
|
111
116
|
msg = self.client.connector.get(MessageEndpoints.scan_queue_status())
|
117
|
+
if msg is None:
|
118
|
+
# msg is None if no scan has been run yet (fresh start)
|
119
|
+
return
|
112
120
|
self.update_queue(msg.content, msg.metadata)
|
113
121
|
|
114
122
|
@Slot(dict, dict)
|
@@ -152,6 +160,13 @@ class BECQueue(BECWidget, QWidget):
|
|
152
160
|
if scan_ids:
|
153
161
|
scan_ids = ", ".join(scan_ids)
|
154
162
|
self.set_row(index, scan_numbers, scan_types, status, scan_ids)
|
163
|
+
busy = (
|
164
|
+
False
|
165
|
+
if all(item.get("status") in ("STOPPED", "COMPLETED", "IDLE") for item in queue_info)
|
166
|
+
else True
|
167
|
+
)
|
168
|
+
self.set_global_state("warning" if busy else "default")
|
169
|
+
self.queue_busy.emit(busy)
|
155
170
|
|
156
171
|
def format_item(self, content: str, status=False) -> QTableWidgetItem:
|
157
172
|
"""
|
@@ -13,8 +13,8 @@ from bec_lib.utils.import_utils import lazy_import_from
|
|
13
13
|
from qtpy.QtCore import QObject, QTimer, Signal, Slot
|
14
14
|
from qtpy.QtWidgets import QHBoxLayout, QTreeWidget, QTreeWidgetItem, QWidget
|
15
15
|
|
16
|
+
from bec_widgets.qt_utils.compact_popup import CompactPopupWidget
|
16
17
|
from bec_widgets.utils.bec_widget import BECWidget
|
17
|
-
from bec_widgets.utils.colors import set_theme
|
18
18
|
from bec_widgets.widgets.bec_status_box.status_item import StatusItem
|
19
19
|
|
20
20
|
if TYPE_CHECKING:
|
@@ -64,7 +64,7 @@ class BECServiceStatusMixin(QObject):
|
|
64
64
|
self._service_update_timer.deleteLater()
|
65
65
|
|
66
66
|
|
67
|
-
class BECStatusBox(BECWidget,
|
67
|
+
class BECStatusBox(BECWidget, CompactPopupWidget):
|
68
68
|
"""An autonomous widget to display the status of BEC services.
|
69
69
|
|
70
70
|
Args:
|
@@ -83,15 +83,13 @@ class BECStatusBox(BECWidget, QWidget):
|
|
83
83
|
def __init__(
|
84
84
|
self,
|
85
85
|
parent=None,
|
86
|
-
box_name: str = "BEC
|
86
|
+
box_name: str = "BEC Servers",
|
87
87
|
client: BECClient = None,
|
88
88
|
bec_service_status_mixin: BECServiceStatusMixin = None,
|
89
89
|
gui_id: str = None,
|
90
90
|
):
|
91
91
|
super().__init__(client=client, gui_id=gui_id)
|
92
|
-
|
93
|
-
self.tree = QTreeWidget(self)
|
94
|
-
self.layout = QHBoxLayout(self)
|
92
|
+
CompactPopupWidget.__init__(self, parent=parent, layout=QHBoxLayout)
|
95
93
|
|
96
94
|
self.box_name = box_name
|
97
95
|
self.status_container = defaultdict(lambda: {"info": None, "item": None, "widget": None})
|
@@ -100,11 +98,13 @@ class BECStatusBox(BECWidget, QWidget):
|
|
100
98
|
bec_service_status_mixin = BECServiceStatusMixin(self, client=self.client)
|
101
99
|
self.bec_service_status = bec_service_status_mixin
|
102
100
|
|
101
|
+
self.label = box_name
|
102
|
+
self.tooltip = "BEC servers health status"
|
103
103
|
self.init_ui()
|
104
104
|
self.bec_service_status.services_update.connect(self.update_service_status)
|
105
105
|
self.bec_core_state.connect(self.update_top_item_status)
|
106
106
|
self.tree.itemDoubleClicked.connect(self.on_tree_item_double_clicked)
|
107
|
-
self.
|
107
|
+
self.addWidget(self.tree)
|
108
108
|
|
109
109
|
def init_ui(self) -> None:
|
110
110
|
"""Init the UI for the BECStatusBox widget, should only take place once."""
|
@@ -121,6 +121,7 @@ class BECStatusBox(BECWidget, QWidget):
|
|
121
121
|
|
122
122
|
def init_ui_tree_widget(self) -> None:
|
123
123
|
"""Initialise the tree widget for the status box."""
|
124
|
+
self.tree = QTreeWidget(self)
|
124
125
|
self.tree.setHeaderHidden(True)
|
125
126
|
# TODO probably here is a problem still with setting the stylesheet
|
126
127
|
self.tree.setStyleSheet(
|
@@ -163,6 +164,7 @@ class BECStatusBox(BECWidget, QWidget):
|
|
163
164
|
status (BECStatus): The state of the core services.
|
164
165
|
"""
|
165
166
|
self.status_container[self.box_name]["info"].status = status
|
167
|
+
self.set_global_state("emergency" if status == "NOTCONNECTED" else "success")
|
166
168
|
self.service_update.emit(self.status_container[self.box_name]["info"])
|
167
169
|
|
168
170
|
def _update_status_container(
|
@@ -308,6 +310,8 @@ if __name__ == "__main__": # pragma: no cover
|
|
308
310
|
|
309
311
|
from qtpy.QtWidgets import QApplication
|
310
312
|
|
313
|
+
from bec_widgets.utils.colors import set_theme
|
314
|
+
|
311
315
|
app = QApplication(sys.argv)
|
312
316
|
set_theme("dark")
|
313
317
|
main_window = BECStatusBox()
|
@@ -307,7 +307,7 @@ class BECImageItem(BECConnector, pg.ImageItem):
|
|
307
307
|
if vrange is not None:
|
308
308
|
self.color_bar.setLevels(low=vrange[0], high=vrange[1])
|
309
309
|
self.color_bar.setImageItem(self)
|
310
|
-
self.parent_image.addItem(self.color_bar
|
310
|
+
self.parent_image.addItem(self.color_bar, row=1, col=1)
|
311
311
|
self.config.color_bar = "simple"
|
312
312
|
elif color_bar_style == "full":
|
313
313
|
# Setting histogram
|
@@ -321,7 +321,7 @@ class BECImageItem(BECConnector, pg.ImageItem):
|
|
321
321
|
)
|
322
322
|
|
323
323
|
# Adding histogram to the layout
|
324
|
-
self.parent_image.addItem(self.color_bar
|
324
|
+
self.parent_image.addItem(self.color_bar, row=1, col=1)
|
325
325
|
|
326
326
|
# save settings
|
327
327
|
self.config.color_bar = "full"
|
@@ -1,6 +1,5 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
from collections import defaultdict
|
4
3
|
from typing import Literal, Optional
|
5
4
|
|
6
5
|
import bec_qthemes
|
@@ -12,6 +11,7 @@ from qtpy.QtWidgets import QApplication, QWidget
|
|
12
11
|
|
13
12
|
from bec_widgets.utils import BECConnector, ConnectionConfig
|
14
13
|
from bec_widgets.utils.crosshair import Crosshair
|
14
|
+
from bec_widgets.utils.fps_counter import FPSCounter
|
15
15
|
from bec_widgets.utils.plot_indicator_items import BECArrowItem, BECTickItem
|
16
16
|
|
17
17
|
logger = bec_logger.logger
|
@@ -51,6 +51,11 @@ class SubplotConfig(ConnectionConfig):
|
|
51
51
|
|
52
52
|
|
53
53
|
class BECViewBox(pg.ViewBox):
|
54
|
+
sigPaint = Signal()
|
55
|
+
|
56
|
+
def paint(self, painter, opt, widget):
|
57
|
+
super().paint(painter, opt, widget)
|
58
|
+
self.sigPaint.emit()
|
54
59
|
|
55
60
|
def itemBoundsChanged(self, item):
|
56
61
|
self._itemBoundsCache.pop(item, None)
|
@@ -79,6 +84,7 @@ class BECPlotBase(BECConnector, pg.GraphicsLayout):
|
|
79
84
|
"set_y_lim",
|
80
85
|
"set_grid",
|
81
86
|
"set_outer_axes",
|
87
|
+
"enable_fps_monitor",
|
82
88
|
"lock_aspect_ratio",
|
83
89
|
"export",
|
84
90
|
"remove",
|
@@ -100,12 +106,13 @@ class BECPlotBase(BECConnector, pg.GraphicsLayout):
|
|
100
106
|
|
101
107
|
self.figure = parent_figure
|
102
108
|
|
103
|
-
# self.plot_item = self.addPlot(row=0, col=0)
|
104
109
|
self.plot_item = pg.PlotItem(viewBox=BECViewBox(parent=self, enableMenu=True), parent=self)
|
105
|
-
self.addItem(self.plot_item, row=
|
110
|
+
self.addItem(self.plot_item, row=1, col=0)
|
106
111
|
|
107
112
|
self.add_legend()
|
108
113
|
self.crosshair = None
|
114
|
+
self.fps_monitor = None
|
115
|
+
self.fps_label = None
|
109
116
|
self.tick_item = BECTickItem(parent=self, plot_item=self.plot_item)
|
110
117
|
self.arrow_item = BECArrowItem(parent=self, plot_item=self.plot_item)
|
111
118
|
self._connect_to_theme_change()
|
@@ -379,6 +386,10 @@ class BECPlotBase(BECConnector, pg.GraphicsLayout):
|
|
379
386
|
"""
|
380
387
|
self.plot_item.enableAutoRange(axis, enabled)
|
381
388
|
|
389
|
+
############################################################
|
390
|
+
###################### Crosshair ###########################
|
391
|
+
############################################################
|
392
|
+
|
382
393
|
def hook_crosshair(self) -> None:
|
383
394
|
"""Hook the crosshair to all plots."""
|
384
395
|
if self.crosshair is None:
|
@@ -417,6 +428,54 @@ class BECPlotBase(BECConnector, pg.GraphicsLayout):
|
|
417
428
|
self.crosshair.clear_markers()
|
418
429
|
self.crosshair.update_markers()
|
419
430
|
|
431
|
+
############################################################
|
432
|
+
##################### FPS Counter ##########################
|
433
|
+
############################################################
|
434
|
+
|
435
|
+
def update_fps_label(self, fps: float) -> None:
|
436
|
+
"""
|
437
|
+
Update the FPS label.
|
438
|
+
|
439
|
+
Args:
|
440
|
+
fps(float): The frames per second.
|
441
|
+
"""
|
442
|
+
if self.fps_label:
|
443
|
+
self.fps_label.setText(f"FPS: {fps:.2f}")
|
444
|
+
|
445
|
+
def hook_fps_monitor(self):
|
446
|
+
"""Hook the FPS monitor to the plot."""
|
447
|
+
if self.fps_monitor is None:
|
448
|
+
# text_color = self.get_text_color()#TODO later
|
449
|
+
self.fps_monitor = FPSCounter(self.plot_item.vb) # text_color=text_color)
|
450
|
+
self.fps_label = pg.LabelItem(justify="right")
|
451
|
+
self.addItem(self.fps_label, row=0, col=0)
|
452
|
+
|
453
|
+
self.fps_monitor.sigFpsUpdate.connect(self.update_fps_label)
|
454
|
+
|
455
|
+
def unhook_fps_monitor(self):
|
456
|
+
"""Unhook the FPS monitor from the plot."""
|
457
|
+
if self.fps_monitor is not None:
|
458
|
+
# Remove Monitor
|
459
|
+
self.fps_monitor.cleanup()
|
460
|
+
self.fps_monitor.deleteLater()
|
461
|
+
self.fps_monitor = None
|
462
|
+
# Remove Label
|
463
|
+
self.removeItem(self.fps_label)
|
464
|
+
self.fps_label.deleteLater()
|
465
|
+
self.fps_label = None
|
466
|
+
|
467
|
+
def enable_fps_monitor(self, enable: bool = True):
|
468
|
+
"""
|
469
|
+
Enable the FPS monitor.
|
470
|
+
|
471
|
+
Args:
|
472
|
+
enable(bool): True to enable, False to disable.
|
473
|
+
"""
|
474
|
+
if enable and self.fps_monitor is None:
|
475
|
+
self.hook_fps_monitor()
|
476
|
+
elif not enable and self.fps_monitor is not None:
|
477
|
+
self.unhook_fps_monitor()
|
478
|
+
|
420
479
|
def export(self):
|
421
480
|
"""Show the Export Dialog of the plot widget."""
|
422
481
|
scene = self.plot_item.scene()
|
@@ -40,6 +40,7 @@ class BECImageWidget(BECWidget, QWidget):
|
|
40
40
|
"set_rotation",
|
41
41
|
"set_log",
|
42
42
|
"set_grid",
|
43
|
+
"enable_fps_monitor",
|
43
44
|
"lock_aspect_ratio",
|
44
45
|
]
|
45
46
|
|
@@ -104,6 +105,9 @@ class BECImageWidget(BECWidget, QWidget):
|
|
104
105
|
icon_name="reset_settings", tooltip="Reset Image Settings"
|
105
106
|
),
|
106
107
|
"separator_3": SeparatorAction(),
|
108
|
+
"fps_monitor": MaterialIconAction(
|
109
|
+
icon_name="speed", tooltip="Show FPS Monitor", checkable=True
|
110
|
+
),
|
107
111
|
"axis_settings": MaterialIconAction(
|
108
112
|
icon_name="settings", tooltip="Open Configuration Dialog"
|
109
113
|
),
|
@@ -150,6 +154,7 @@ class BECImageWidget(BECWidget, QWidget):
|
|
150
154
|
self.toolbar.widgets["reset"].action.triggered.connect(self.reset_settings)
|
151
155
|
# sepatator
|
152
156
|
self.toolbar.widgets["axis_settings"].action.triggered.connect(self.show_axis_settings)
|
157
|
+
self.toolbar.widgets["fps_monitor"].action.toggled.connect(self.enable_fps_monitor)
|
153
158
|
|
154
159
|
###################################
|
155
160
|
# Dialog Windows
|
@@ -450,6 +455,18 @@ class BECImageWidget(BECWidget, QWidget):
|
|
450
455
|
self.toolbar.widgets["rectangle_mode"].action.setChecked(False)
|
451
456
|
self._image.plot_item.getViewBox().setMouseMode(pg.ViewBox.PanMode)
|
452
457
|
|
458
|
+
@SafeSlot()
|
459
|
+
def enable_fps_monitor(self, enabled: bool):
|
460
|
+
"""
|
461
|
+
Enable the FPS monitor of the plot widget.
|
462
|
+
|
463
|
+
Args:
|
464
|
+
enabled(bool): If True, enable the FPS monitor.
|
465
|
+
"""
|
466
|
+
self._image.enable_fps_monitor(enabled)
|
467
|
+
if self.toolbar.widgets["fps_monitor"].action.isChecked() != enabled:
|
468
|
+
self.toolbar.widgets["fps_monitor"].action.setChecked(enabled)
|
469
|
+
|
453
470
|
def export(self):
|
454
471
|
"""
|
455
472
|
Show the export dialog for the plot widget.
|
@@ -52,6 +52,7 @@ class BECWaveformWidget(BECWidget, QWidget):
|
|
52
52
|
"set_legend_label_size",
|
53
53
|
"set_auto_range",
|
54
54
|
"set_grid",
|
55
|
+
"enable_fps_monitor",
|
55
56
|
"lock_aspect_ratio",
|
56
57
|
"export",
|
57
58
|
"export_to_matplotlib",
|
@@ -118,9 +119,7 @@ class BECWaveformWidget(BECWidget, QWidget):
|
|
118
119
|
"fit_params": MaterialIconAction(
|
119
120
|
icon_name="monitoring", tooltip="Open Fitting Parameters"
|
120
121
|
),
|
121
|
-
"
|
122
|
-
icon_name="settings", tooltip="Open Configuration Dialog"
|
123
|
-
),
|
122
|
+
"separator_3": SeparatorAction(),
|
124
123
|
"crosshair": MaterialIconAction(
|
125
124
|
icon_name="point_scan", tooltip="Show Crosshair", checkable=True
|
126
125
|
),
|
@@ -129,6 +128,13 @@ class BECWaveformWidget(BECWidget, QWidget):
|
|
129
128
|
tooltip="Add ROI region for DAP",
|
130
129
|
checkable=True,
|
131
130
|
),
|
131
|
+
"separator_4": SeparatorAction(),
|
132
|
+
"fps_monitor": MaterialIconAction(
|
133
|
+
icon_name="speed", tooltip="Show FPS Monitor", checkable=True
|
134
|
+
),
|
135
|
+
"axis_settings": MaterialIconAction(
|
136
|
+
icon_name="settings", tooltip="Open Configuration Dialog"
|
137
|
+
),
|
132
138
|
},
|
133
139
|
target_widget=self,
|
134
140
|
)
|
@@ -186,6 +192,7 @@ class BECWaveformWidget(BECWidget, QWidget):
|
|
186
192
|
self.toolbar.widgets["axis_settings"].action.triggered.connect(self.show_axis_settings)
|
187
193
|
self.toolbar.widgets["crosshair"].action.triggered.connect(self.waveform.toggle_crosshair)
|
188
194
|
self.toolbar.widgets["roi_select"].action.toggled.connect(self.waveform.toggle_roi)
|
195
|
+
self.toolbar.widgets["fps_monitor"].action.toggled.connect(self.enable_fps_monitor)
|
189
196
|
# self.toolbar.widgets["import"].action.triggered.connect(
|
190
197
|
# lambda: self.load_config(path=None, gui=True)
|
191
198
|
# )
|
@@ -594,6 +601,8 @@ class BECWaveformWidget(BECWidget, QWidget):
|
|
594
601
|
checked(bool): If True, enable the linear region selector.
|
595
602
|
"""
|
596
603
|
self.waveform.toggle_roi(checked)
|
604
|
+
if self.toolbar.widgets["roi_select"].action.isChecked() != checked:
|
605
|
+
self.toolbar.widgets["roi_select"].action.setChecked(checked)
|
597
606
|
|
598
607
|
def select_roi(self, region: tuple):
|
599
608
|
"""
|
@@ -604,6 +613,17 @@ class BECWaveformWidget(BECWidget, QWidget):
|
|
604
613
|
"""
|
605
614
|
self.waveform.select_roi(region)
|
606
615
|
|
616
|
+
def enable_fps_monitor(self, enabled: bool):
|
617
|
+
"""
|
618
|
+
Enable the FPS monitor of the plot widget.
|
619
|
+
|
620
|
+
Args:
|
621
|
+
enabled(bool): If True, enable the FPS monitor.
|
622
|
+
"""
|
623
|
+
self.waveform.enable_fps_monitor(enabled)
|
624
|
+
if self.toolbar.widgets["fps_monitor"].action.isChecked() != enabled:
|
625
|
+
self.toolbar.widgets["fps_monitor"].action.setChecked(enabled)
|
626
|
+
|
607
627
|
@SafeSlot()
|
608
628
|
def _auto_range_from_toolbar(self):
|
609
629
|
"""
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: bec_widgets
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.117.0
|
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
|
@@ -32,4 +32,4 @@ Provides-Extra: pyqt6
|
|
32
32
|
Requires-Dist: pyqt6-webengine>=6.7; extra == 'pyqt6'
|
33
33
|
Requires-Dist: pyqt6>=6.7; extra == 'pyqt6'
|
34
34
|
Provides-Extra: pyside6
|
35
|
-
Requires-Dist: pyside6
|
35
|
+
Requires-Dist: pyside6~=6.7.2; extra == 'pyside6'
|
@@ -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=
|
5
|
+
CHANGELOG.md,sha256=P2FvQRmkrzZeRyx-2Okb6dqpPawiUEEua4eQjG0ffNI,7492
|
6
6
|
LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
|
7
|
-
PKG-INFO,sha256=
|
7
|
+
PKG-INFO,sha256=qzAx_QzNjl7iO4_f8Bz9YYq3XG9n3Lv2VGGKUY5X48M,1334
|
8
8
|
README.md,sha256=Od69x-RS85Hph0-WwWACwal4yUd67XkEn4APEfHhHFw,2649
|
9
|
-
pyproject.toml,sha256=
|
9
|
+
pyproject.toml,sha256=kyGOtgZp4UfDCXDm7NnGWUox2z3FHW5lri9ZUU-g3Yg,2594
|
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
|
@@ -18,13 +18,13 @@ bec_widgets/applications/bec_app.py,sha256=PptBknsnhWm5GSE-xBps4EAYP3f9i-q9YmUMR
|
|
18
18
|
bec_widgets/applications/alignment/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
19
19
|
bec_widgets/applications/alignment/alignment_1d/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
20
20
|
bec_widgets/applications/alignment/alignment_1d/alignment_1d.py,sha256=eGqEXKVz4kSdaIBZAKfuI4pwYoLWwKyLjTY1eB31kgk,11200
|
21
|
-
bec_widgets/applications/alignment/alignment_1d/alignment_1d.ui,sha256=
|
21
|
+
bec_widgets/applications/alignment/alignment_1d/alignment_1d.ui,sha256=CQz0UAXhWI4As_dsgfZUqCtYoqEAgEJl7IZWP7YxA5I,28940
|
22
22
|
bec_widgets/assets/app_icons/BEC-General-App.png,sha256=hc2ktly53DZAbl_rE3cb-vdRa5gtdCmBEjfwm2y5P4g,447581
|
23
23
|
bec_widgets/assets/app_icons/alignment_1d.png,sha256=5VouaWieb4lVv3wUBNHaO5ovUW2Fk25aTKYQzOWy0mg,2071069
|
24
24
|
bec_widgets/assets/app_icons/bec_widgets_icon.png,sha256=K8dgGwIjalDh9PRHUsSQBqgdX7a00nM3igZdc20pkYM,1747017
|
25
25
|
bec_widgets/cli/__init__.py,sha256=d0Q6Fn44e7wFfLabDOBxpcJ1DPKWlFunGYDUBmO-4hA,22
|
26
26
|
bec_widgets/cli/auto_updates.py,sha256=DwzRChcFIWPH2kCYvp8H7dXvyYSKGYv6LwCmK2sDR2E,5676
|
27
|
-
bec_widgets/cli/client.py,sha256=
|
27
|
+
bec_widgets/cli/client.py,sha256=5fPUNDWvzBii-0oMOL76IhKffN88q1vbrx2P7Uh90TE,83195
|
28
28
|
bec_widgets/cli/client_utils.py,sha256=EdDfo3uuYAWtZiDGGu3_GPnl94FSLkNG2N_4I9FNfMc,11809
|
29
29
|
bec_widgets/cli/generate_cli.py,sha256=C5SOlUeDzFgEptgpa5vdiF6c-YILLcfILZZtk9jr_H0,6637
|
30
30
|
bec_widgets/cli/rpc_register.py,sha256=QxXUZu5XNg00Yf5O3UHWOXg3-f_pzKjjoZYMOa-MOJc,2216
|
@@ -45,6 +45,7 @@ bec_widgets/examples/plugin_example_pyside/tictactoe.py,sha256=s3rCurXloVcmMdzZi
|
|
45
45
|
bec_widgets/examples/plugin_example_pyside/tictactoeplugin.py,sha256=MFMwONn4EZ3V8DboEG4I3BXpURE9JDbKB7XTzzfZl5w,1978
|
46
46
|
bec_widgets/examples/plugin_example_pyside/tictactoetaskmenu.py,sha256=V6OVnBTS-60zjQ2FAs88Ldjm1MfoMROfiQZZu6Guav8,2379
|
47
47
|
bec_widgets/qt_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
48
|
+
bec_widgets/qt_utils/compact_popup.py,sha256=DQel3iVjRYn6C5cR33ADSPyZObuMWSKwJYbwudb0o1k,8474
|
48
49
|
bec_widgets/qt_utils/error_popups.py,sha256=y9gKKWaafp468ioHr96nBhf02ZpEgjDc-BAVOTWh-e8,7680
|
49
50
|
bec_widgets/qt_utils/palette_viewer.py,sha256=PGhJ-4XI0f7gNnC1djNgcIHYg6HDO6hPju4pfWj9rvg,6311
|
50
51
|
bec_widgets/qt_utils/redis_message_waiter.py,sha256=fvL_QgC0cTDv_FPJdRyp5AKjf401EJU4z3r38p47ydY,1745
|
@@ -61,6 +62,7 @@ bec_widgets/utils/colors.py,sha256=aUQkDMTRjTjS9lQfgO5NrUllU2r4ygDTTSUROtTBX90,1
|
|
61
62
|
bec_widgets/utils/container_utils.py,sha256=0wr3ZfuMiAFKCrQHVjxjw-Vuk8wsHdridqcjy2eY840,1531
|
62
63
|
bec_widgets/utils/crosshair.py,sha256=8lik9k69WI2WMj5FGLbrKtny9duxqXUJAhpX8tHoyp0,11543
|
63
64
|
bec_widgets/utils/entry_validator.py,sha256=3skJIsUwTYicT76AMHm_M78RiWtUgyD2zb-Rxo2HdHQ,1313
|
65
|
+
bec_widgets/utils/fps_counter.py,sha256=seuCWwiNP5q2e2OEztloa66pNb3Sygh-0lEHAcYaDfc,2612
|
64
66
|
bec_widgets/utils/generate_designer_plugin.py,sha256=eidqauS8YLgoxkPntPL0oSG_lYqI2D7fSyOZvOtCU_U,5891
|
65
67
|
bec_widgets/utils/layout_manager.py,sha256=H0nKsIMaPxRkof1MEXlSmW6w1dFxA6astaGzf4stI84,4727
|
66
68
|
bec_widgets/utils/linear_region_selector.py,sha256=83qMSGnxCePdI5UL8_M4sMeK_BU9sZBzcw0o3Z_Jgxw,3286
|
@@ -84,12 +86,12 @@ bec_widgets/widgets/bec_progressbar/bec_progress_bar_plugin.py,sha256=b0b0F37Hrw
|
|
84
86
|
bec_widgets/widgets/bec_progressbar/bec_progressbar.py,sha256=kkmpe5o9RPOCIKKPp0jjfQORLT8XKW_e-ETEl5Zmltk,7980
|
85
87
|
bec_widgets/widgets/bec_progressbar/register_bec_progress_bar.py,sha256=ZcGLPYEwkrbSOpxQeuZJRRVV3yXvcFh133hnlKIQGKw,488
|
86
88
|
bec_widgets/widgets/bec_queue/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
87
|
-
bec_widgets/widgets/bec_queue/bec_queue.py,sha256=
|
89
|
+
bec_widgets/widgets/bec_queue/bec_queue.py,sha256=5_uhcstSnbcQ__SmkWRfomEvDfwaJv3vTetXUV6w7Eo,8585
|
88
90
|
bec_widgets/widgets/bec_queue/bec_queue.pyproject,sha256=VhoNmAv1DQUl9dg7dELyf5i4pZ5k65N3GnqOYiSwbQo,27
|
89
91
|
bec_widgets/widgets/bec_queue/bec_queue_plugin.py,sha256=cotVUNKphAXQAp6mWtKoyzJ-vyAnfd86tGf4yNp0CjU,1341
|
90
92
|
bec_widgets/widgets/bec_queue/register_bec_queue.py,sha256=XnwtUSa1asK1b80knKWodcyX9qJy4DnKsQL_FoDfZy4,463
|
91
93
|
bec_widgets/widgets/bec_status_box/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
92
|
-
bec_widgets/widgets/bec_status_box/bec_status_box.py,sha256=
|
94
|
+
bec_widgets/widgets/bec_status_box/bec_status_box.py,sha256=udxOoTqO_qVO08B8kmVzn6YmAMLsAZBOERdm18hZIUc,13272
|
93
95
|
bec_widgets/widgets/bec_status_box/bec_status_box.pyproject,sha256=JWtx3Csfn2h7ODtk10HtyBNLf6tFIqyU6g04rMWOO1U,32
|
94
96
|
bec_widgets/widgets/bec_status_box/bec_status_box_plugin.py,sha256=UmsXAmeHg7FRkzirOLBPi3LwbRbG75w8LglYt4jn6Fc,1412
|
95
97
|
bec_widgets/widgets/bec_status_box/register_bec_status_box.py,sha256=EiQITnkNw7IU7hE776wAeXro97eZd9XlsB9essgCebE,481
|
@@ -162,20 +164,20 @@ bec_widgets/widgets/figure/figure.py,sha256=IzQaV_9utjViJyjMydOa3-EJ9k-FVG2PTVm8
|
|
162
164
|
bec_widgets/widgets/figure/plots/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
163
165
|
bec_widgets/widgets/figure/plots/axis_settings.py,sha256=grgrX4t4eAzccW4jj4HYtMSxy8Wgcd9N9J1aU7UHtIs,3723
|
164
166
|
bec_widgets/widgets/figure/plots/axis_settings.ui,sha256=ye-guaRU_jhu7sHZS-9AjBjLrCtA1msOD0dszu4o9x8,11785
|
165
|
-
bec_widgets/widgets/figure/plots/plot_base.py,sha256=
|
167
|
+
bec_widgets/widgets/figure/plots/plot_base.py,sha256=FIPvigIHenScR3T1NitRdlY_CXJmuAjCY8fv3GQzrRM,18053
|
166
168
|
bec_widgets/widgets/figure/plots/image/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
167
|
-
bec_widgets/widgets/figure/plots/image/image.py,sha256=
|
168
|
-
bec_widgets/widgets/figure/plots/image/image_item.py,sha256=
|
169
|
+
bec_widgets/widgets/figure/plots/image/image.py,sha256=FmvVVKLtMOAvaRL1tF30KLO0yQVCZqxCqydQIesKgdc,25044
|
170
|
+
bec_widgets/widgets/figure/plots/image/image_item.py,sha256=TwHo6FwCiQgJBdr-KKy_7Y_vYSB0pPjBl1AubuZSrE0,11002
|
169
171
|
bec_widgets/widgets/figure/plots/image/image_processor.py,sha256=GeTtWjbldy6VejMwPGQgM-o3d6bmLglCjdoktu19xfA,5262
|
170
172
|
bec_widgets/widgets/figure/plots/motor_map/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
171
173
|
bec_widgets/widgets/figure/plots/motor_map/motor_map.py,sha256=AiDq4bmcEoj9PlkRQtHCk-5cwvOFGPBcfxPNNr8E53Y,18399
|
172
174
|
bec_widgets/widgets/figure/plots/waveform/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
173
|
-
bec_widgets/widgets/figure/plots/waveform/waveform.py,sha256=
|
175
|
+
bec_widgets/widgets/figure/plots/waveform/waveform.py,sha256=WmFOwtDL5i7RSamB2B-PQS3T8BaKv-pv2Mp2ggh-t3U,56738
|
174
176
|
bec_widgets/widgets/figure/plots/waveform/waveform_curve.py,sha256=RUo4GfXwlaCei8BBvWBQF3IEB8h-KgpvaHur6JUvT6s,8682
|
175
177
|
bec_widgets/widgets/image/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
176
178
|
bec_widgets/widgets/image/bec_image_widget.pyproject,sha256=PHisdBo5_5UCApd27GkizzqgfdjsDx2bFZa_p9LiSW8,30
|
177
179
|
bec_widgets/widgets/image/bec_image_widget_plugin.py,sha256=3nOHJTukHsEkaCLAivPHIY4qdshAj86LUKb5fYF3C-Y,1369
|
178
|
-
bec_widgets/widgets/image/image_widget.py,sha256=
|
180
|
+
bec_widgets/widgets/image/image_widget.py,sha256=va8IwMWgKUhtmmig2npFjVWJgTnIdnGMFhqFHuoQvWo,17040
|
179
181
|
bec_widgets/widgets/image/register_bec_image_widget.py,sha256=01YLZQTMSSIXvH1TSL-1AYsRs1a4EbSwKLVAwh9AjeA,478
|
180
182
|
bec_widgets/widgets/jupyter_console/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
181
183
|
bec_widgets/widgets/jupyter_console/jupyter_console.py,sha256=-e7HQOECeH5eDrJYh4BFIzRL78LDkooU4otabyN0aX4,2343
|
@@ -251,7 +253,7 @@ bec_widgets/widgets/waveform/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NM
|
|
251
253
|
bec_widgets/widgets/waveform/bec_waveform_widget.pyproject,sha256=GLD8GN9dXx9wNbtnevrxqqcwk7vKV-Uv8QYSycdaoaI,33
|
252
254
|
bec_widgets/widgets/waveform/bec_waveform_widget_plugin.py,sha256=qSQTeCzIUn8rgDkjIM47Rr3-fqg1uk8rDf_lCoY9gZw,1402
|
253
255
|
bec_widgets/widgets/waveform/register_bec_waveform_widget.py,sha256=qZHVZH_lP2hvzkG1Ra0EyrXlMeLkRCy0aceH-bfJ1cs,490
|
254
|
-
bec_widgets/widgets/waveform/waveform_widget.py,sha256=
|
256
|
+
bec_widgets/widgets/waveform/waveform_widget.py,sha256=HnBRkAPecKV1U_gqLF6seyQnNcqFeR3D4olLqNeNQAw,25664
|
255
257
|
bec_widgets/widgets/waveform/waveform_popups/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
256
258
|
bec_widgets/widgets/waveform/waveform_popups/curve_dialog/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
257
259
|
bec_widgets/widgets/waveform/waveform_popups/curve_dialog/curve_dialog.py,sha256=VxbAtI_ZLfkrkTXqImQcNPwKDqFRWEj-vI8v6mmVMJ8,13025
|
@@ -263,8 +265,8 @@ bec_widgets/widgets/website/register_website_widget.py,sha256=LIQJpV9uqcBiPR9cEA
|
|
263
265
|
bec_widgets/widgets/website/website.py,sha256=42pncCc_zI2eqeMArIurVmPUukRo5bTxa2h1Skah-io,3012
|
264
266
|
bec_widgets/widgets/website/website_widget.pyproject,sha256=scOiV3cV1_BjbzpPzy2N8rIJL5P2qIZz8ObTJ-Uvdtg,25
|
265
267
|
bec_widgets/widgets/website/website_widget_plugin.py,sha256=pz38_C2cZ0yvPPS02wdIPcmhFo_yiwUhflsASocAPQQ,1341
|
266
|
-
bec_widgets-0.
|
267
|
-
bec_widgets-0.
|
268
|
-
bec_widgets-0.
|
269
|
-
bec_widgets-0.
|
270
|
-
bec_widgets-0.
|
268
|
+
bec_widgets-0.117.0.dist-info/METADATA,sha256=qzAx_QzNjl7iO4_f8Bz9YYq3XG9n3Lv2VGGKUY5X48M,1334
|
269
|
+
bec_widgets-0.117.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
|
270
|
+
bec_widgets-0.117.0.dist-info/entry_points.txt,sha256=dItMzmwA1wizJ1Itx15qnfJ0ZzKVYFLVJ1voxT7K7D4,214
|
271
|
+
bec_widgets-0.117.0.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
|
272
|
+
bec_widgets-0.117.0.dist-info/RECORD,,
|
pyproject.toml
CHANGED
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "bec_widgets"
|
7
|
-
version = "0.
|
7
|
+
version = "0.117.0"
|
8
8
|
description = "BEC Widgets"
|
9
9
|
requires-python = ">=3.10"
|
10
10
|
classifiers = [
|
@@ -38,7 +38,7 @@ dev = [
|
|
38
38
|
"pytest~=8.0",
|
39
39
|
]
|
40
40
|
pyqt6 = ["PyQt6>=6.7", "PyQt6-WebEngine>=6.7"]
|
41
|
-
pyside6 = ["PySide6
|
41
|
+
pyside6 = ["PySide6~=6.7.2"]
|
42
42
|
|
43
43
|
[project.urls]
|
44
44
|
"Bug Tracker" = "https://gitlab.psi.ch/bec/bec_widgets/issues"
|
File without changes
|
File without changes
|
File without changes
|