bec-widgets 0.114.0__py3-none-any.whl → 0.116.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 +62 -51
- PKG-INFO +3 -3
- bec_widgets/applications/alignment/alignment_1d/alignment_1d.py +10 -10
- bec_widgets/applications/alignment/alignment_1d/alignment_1d.ui +96 -42
- bec_widgets/applications/bec_app.py +84 -0
- bec_widgets/qt_utils/compact_popup.py +223 -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-0.114.0.dist-info → bec_widgets-0.116.0.dist-info}/METADATA +3 -3
- {bec_widgets-0.114.0.dist-info → bec_widgets-0.116.0.dist-info}/RECORD +14 -12
- {bec_widgets-0.114.0.dist-info → bec_widgets-0.116.0.dist-info}/entry_points.txt +1 -0
- pyproject.toml +4 -3
- {bec_widgets-0.114.0.dist-info → bec_widgets-0.116.0.dist-info}/WHEEL +0 -0
- {bec_widgets-0.114.0.dist-info → bec_widgets-0.116.0.dist-info}/licenses/LICENSE +0 -0
CHANGELOG.md
CHANGED
@@ -1,36 +1,71 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
|
4
|
+
## v0.116.0 (2024-10-11)
|
5
|
+
|
6
|
+
### Build System
|
7
|
+
|
8
|
+
* build: fix PySide6 to 6.7.2 ([`908dbc1`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/908dbc1760da5b323722207163f00850b84fb90b))
|
9
|
+
|
10
|
+
### Features
|
11
|
+
|
12
|
+
* feat: UI changes to have top toolbar with compact popup widgets (fix issue #360) ([`499b6b9`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/499b6b9a12efd931b5728b519404c41a7e29e4d6))
|
13
|
+
|
14
|
+
* feat: adapt BECQueue and BECStatusBox widgets to use CompactPopupWidget ([`94ce92f`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/94ce92f5b054d25ea3bb7976c1f75e14b78b9edc))
|
15
|
+
|
16
|
+
* feat: add 'CompactPopupWidget' container widget
|
17
|
+
|
18
|
+
Makes it easy to write widgets which can have a compact
|
19
|
+
representation with LED-like global state indicator,
|
20
|
+
with the possibility to display a popup dialog with more
|
21
|
+
complete UI ([`49268e3`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/49268e3829406d70b09e4d88989812f5578e46f4))
|
22
|
+
|
23
|
+
|
24
|
+
## v0.115.0 (2024-10-08)
|
25
|
+
|
26
|
+
### Features
|
27
|
+
|
28
|
+
* feat: add bec-app script to launch applications ([`8bf4842`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/8bf48427884338672a8e3de3deb20439b0bfdf99))
|
29
|
+
|
30
|
+
### Fixes
|
31
|
+
|
32
|
+
* fix: make Alignment1D a MainWindow as it is an application ([`c5e9ed6`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/c5e9ed6e422acb908e1ada32822f5d7cc256ade7))
|
33
|
+
|
34
|
+
* fix: adjust bec_qthemes dependency ([`b207e45`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/b207e45a67818ee061272ce00a09fe7ea31cd1ba))
|
35
|
+
|
36
|
+
|
3
37
|
## v0.114.0 (2024-10-02)
|
4
38
|
|
5
|
-
###
|
39
|
+
### Features
|
6
40
|
|
7
|
-
* feat: new
|
41
|
+
* feat: new 'scan_axis' signal
|
8
42
|
|
9
|
-
Signal is emitted before
|
43
|
+
Signal is emitted before "scan_started", to inform about scan positioner
|
10
44
|
and (start, stop) positions. In case of multiple bundles, the signal
|
11
45
|
is emitted multiple times. ([`f084e25`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/f084e2514bc9459cccaa951b79044bc25884e738))
|
12
46
|
|
13
|
-
###
|
47
|
+
### Fixes
|
14
48
|
|
15
49
|
* fix: prevent exception when empty string updates are coming from widget ([`04cfb1e`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/04cfb1edf19437d54f07b868bcf3cfc2a35fd3bc))
|
16
50
|
|
17
|
-
* fix: use new
|
51
|
+
* fix: use new 'scan_axis' signal, to set_x and select x axis on waveform
|
18
52
|
|
19
53
|
Fixes #361, do not try to change x axis when not permitted ([`efa2763`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/efa276358b0f5a45cce9fa84fa5f9aafaf4284f7))
|
20
54
|
|
55
|
+
|
21
56
|
## v0.113.0 (2024-10-02)
|
22
57
|
|
23
|
-
###
|
58
|
+
### Features
|
24
59
|
|
25
60
|
* feat: add first draft for alignment_1d GUI ([`63c24f9`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/63c24f97a355edaa928b6e222909252b276bcada))
|
26
61
|
|
27
62
|
* feat: add move to position button to lmfit dialog ([`281cb27`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/281cb27d8b5433e27a7ba0ca0a19e4b45b9c544f))
|
28
63
|
|
29
|
-
###
|
64
|
+
### Fixes
|
30
65
|
|
31
66
|
* fix: add is_log checks and functionality to plot_indicator_items ([`0f9953e`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/0f9953e8fdcf3f9b5a09f994c69edb6b34756df9))
|
32
67
|
|
33
|
-
###
|
68
|
+
### Refactoring
|
34
69
|
|
35
70
|
* refactor: various minor improvements for the alignment gui ([`f554f3c`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/f554f3c1672c4fe32968a5991dc98802556a6f3b))
|
36
71
|
|
@@ -44,7 +79,7 @@ Fixes #361, do not try to change x axis when not permitted ([`efa2763`](https://
|
|
44
79
|
|
45
80
|
* refactor: use accent colors for bec_status_box icons; closes #338 ([`e039304`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/e039304fd3ee03dc4a3fa22a69c207139e0c0d28))
|
46
81
|
|
47
|
-
###
|
82
|
+
### Testing
|
48
83
|
|
49
84
|
* test: add tests for scan_status_callback ([`dc0c825`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/dc0c825fd594c093a24543ff803d6c6564010e92))
|
50
85
|
|
@@ -52,6 +87,7 @@ Fixes #361, do not try to change x axis when not permitted ([`efa2763`](https://
|
|
52
87
|
|
53
88
|
* feat : Add bec_signal_proxy to handle signals with option to unblock them manually. ([`1dcfeb6`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/1dcfeb6cfce3c69f0c5401731d4d3f9a1981b22e))
|
54
89
|
|
90
|
+
|
55
91
|
## v0.112.1 (2024-09-19)
|
56
92
|
|
57
93
|
### Documentation
|
@@ -60,27 +96,29 @@ Fixes #361, do not try to change x axis when not permitted ([`efa2763`](https://
|
|
60
96
|
|
61
97
|
* docs(device_box): updated screenshot ([`c8e614b`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/c8e614b575b48be788a6389a7aa0cfa033d86ab8))
|
62
98
|
|
63
|
-
###
|
99
|
+
### Fixes
|
64
100
|
|
65
101
|
* fix: test e2e dap wait_for_fit ([`b2f7d3c`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/b2f7d3c5f3f4bf00cc628f788e2c278ebb5688ae))
|
66
102
|
|
103
|
+
|
67
104
|
## v0.112.0 (2024-09-17)
|
68
105
|
|
69
|
-
###
|
106
|
+
### Features
|
70
107
|
|
71
108
|
* feat: console: various improvements, auto-adapt rows to widget size, Qt Designer plugin ([`286ad71`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/286ad7196b0b8562d648fb304eab7d759b6a959b))
|
72
109
|
|
110
|
+
|
73
111
|
## v0.111.0 (2024-09-17)
|
74
112
|
|
75
113
|
### Documentation
|
76
114
|
|
77
115
|
* docs(position_indicator): updated position indicator documentation and added designer properties ([`60f7d54`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/60f7d54e2b4c3129de6c95729b8b4aea1757174f))
|
78
116
|
|
79
|
-
###
|
117
|
+
### Features
|
80
118
|
|
81
119
|
* feat(position_indicator): improved design and added more customization options ([`d15b222`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/d15b22250fbceb708d89872c0380693e04acb107))
|
82
120
|
|
83
|
-
###
|
121
|
+
### Fixes
|
84
122
|
|
85
123
|
* fix(position_indicator): fixed user access ([`dd932dd`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/dd932dd8f3910ab67ec8403124f4e176d048e542))
|
86
124
|
|
@@ -90,74 +128,47 @@ Fixes #361, do not try to change x axis when not permitted ([`efa2763`](https://
|
|
90
128
|
|
91
129
|
* fix(palette viewer): fixed background for tool tip ([`9045323`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/9045323049d2a39c36fc8845f3b2883d6933436b))
|
92
130
|
|
131
|
+
|
93
132
|
## v0.110.0 (2024-09-12)
|
94
133
|
|
95
|
-
###
|
134
|
+
### Features
|
96
135
|
|
97
136
|
* feat(palette_viewer): added widget to display the current palette and accent colors ([`a8576c1`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/a8576c164cad17746ec4fcd5c775fb78f70c055c))
|
98
137
|
|
138
|
+
|
99
139
|
## v0.109.1 (2024-09-09)
|
100
140
|
|
101
|
-
###
|
141
|
+
### Fixes
|
102
142
|
|
103
143
|
* fix: refactor textbox widget, remove inheritance, adhere to bec style; closes #324 ([`b0d786b`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/b0d786b991677c0846a0c6ba3f2252d48d94ccaa))
|
104
144
|
|
145
|
+
|
105
146
|
## v0.109.0 (2024-09-06)
|
106
147
|
|
107
|
-
###
|
148
|
+
### Features
|
108
149
|
|
109
150
|
* feat(accent colors): added helper function to get all accent colors ([`84a59f7`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/84a59f70eed6d8a3c3aeeabc77a5f9ea4e864f61))
|
110
151
|
|
111
|
-
###
|
152
|
+
### Fixes
|
112
153
|
|
113
154
|
* fix(theme): fixed theme access for themecontainer ([`de303f0`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/de303f0227fc9d3a74a0410f1e7999ac5132273c))
|
114
155
|
|
156
|
+
|
115
157
|
## v0.108.0 (2024-09-06)
|
116
158
|
|
117
159
|
### Documentation
|
118
160
|
|
119
161
|
* docs(progressbar): added docs ([`7d07cea`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/7d07cea946f9c884477b01bebfb60b332ff09e0a))
|
120
162
|
|
121
|
-
###
|
163
|
+
### Features
|
122
164
|
|
123
165
|
* feat(progressbar): added bec progressbar ([`f6d1d0b`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/f6d1d0bbe3ba30a3b7291cd36a1f7f8e6bd5b895))
|
124
166
|
|
125
167
|
* feat(generate_cli): added support for property and qproperty setter ([`a52182d`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/a52182dca978833bfc3fad755c596d3a2ef45c42))
|
126
168
|
|
127
|
-
## v0.107.0 (2024-09-06)
|
128
|
-
|
129
|
-
### Documentation
|
130
169
|
|
131
|
-
|
132
|
-
|
133
|
-
### Feature
|
134
|
-
|
135
|
-
* feat: add roi select for dap, allow automatic clear curves on plot request ([`7bdca84`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/7bdca8431496fe6562d2c28f5a6af869d1a2e654))
|
170
|
+
## v0.107.0 (2024-09-06)
|
136
171
|
|
137
|
-
###
|
172
|
+
### Refactoring
|
138
173
|
|
139
174
|
* refactor: change style to bec_accent_colors ([`bd126dd`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/bd126dddbbec3e6c448cce263433d328d577c5c0))
|
140
|
-
|
141
|
-
### Test
|
142
|
-
|
143
|
-
* test: add tests, including extension to end-2-end test ([`b1aff6d`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/b1aff6d791ff847eb2f628e66ccaa4672fdeea08))
|
144
|
-
|
145
|
-
## v0.106.0 (2024-09-05)
|
146
|
-
|
147
|
-
### Feature
|
148
|
-
|
149
|
-
* feat(plot_base): toggle to switch outer axes for plotting widgets ([`06d7741`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/06d7741622aea8556208cd17cae521c37333f8b6))
|
150
|
-
|
151
|
-
### Refactor
|
152
|
-
|
153
|
-
* refactor: use DAPComboBox in curve_dialog selection ([`998a745`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/998a7451335b1b35c3e18691d3bab8d882e2d30b))
|
154
|
-
|
155
|
-
### Test
|
156
|
-
|
157
|
-
* test: fix tests ([`6b15abc`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/6b15abcc73170cb49292741a619a08ee615e6250))
|
158
|
-
|
159
|
-
## v0.105.0 (2024-09-04)
|
160
|
-
|
161
|
-
### Refactor
|
162
|
-
|
163
|
-
* refactor: cleanup and renaming of slot/signals ([`0fd5cee`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/0fd5cee77611b6645326eaefa68455ea8de26597))
|
PKG-INFO
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: bec_widgets
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.116.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
|
@@ -11,7 +11,7 @@ Classifier: Topic :: Scientific/Engineering
|
|
11
11
|
Requires-Python: >=3.10
|
12
12
|
Requires-Dist: bec-ipython-client>=2.21.4,~=2.21
|
13
13
|
Requires-Dist: bec-lib>=2.21.4,~=2.21
|
14
|
-
Requires-Dist: bec-qthemes>=0.
|
14
|
+
Requires-Dist: bec-qthemes>=0.7,~=0.7
|
15
15
|
Requires-Dist: black~=24.0
|
16
16
|
Requires-Dist: isort>=5.13.2,~=5.13
|
17
17
|
Requires-Dist: pydantic~=2.0
|
@@ -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'
|
@@ -10,7 +10,7 @@ from bec_lib.device import Signal as BECSignal
|
|
10
10
|
from bec_lib.endpoints import MessageEndpoints
|
11
11
|
from qtpy.QtCore import QSize, Signal
|
12
12
|
from qtpy.QtGui import QIcon
|
13
|
-
from qtpy.QtWidgets import QCheckBox, QDoubleSpinBox, QPushButton, QSpinBox
|
13
|
+
from qtpy.QtWidgets import QCheckBox, QDoubleSpinBox, QMainWindow, QPushButton, QSpinBox
|
14
14
|
|
15
15
|
import bec_widgets
|
16
16
|
from bec_widgets.qt_utils.error_popups import SafeSlot as Slot
|
@@ -29,15 +29,13 @@ from bec_widgets.widgets.waveform.waveform_widget import BECWaveformWidget
|
|
29
29
|
MODULE_PATH = os.path.dirname(bec_widgets.__file__)
|
30
30
|
|
31
31
|
|
32
|
-
class Alignment1D(BECWidget,
|
32
|
+
class Alignment1D(BECWidget, QMainWindow):
|
33
33
|
"""Alignment GUI to perform 1D scans"""
|
34
34
|
|
35
35
|
# Emit a signal when a motion is ongoing
|
36
36
|
motion_is_active = Signal(bool)
|
37
37
|
|
38
|
-
def __init__(
|
39
|
-
self, parent: Optional[QWidget] = None, client=None, gui_id: Optional[str] = None
|
40
|
-
) -> None:
|
38
|
+
def __init__(self, client=None, gui_id: Optional[str] = None) -> None:
|
41
39
|
"""Initialise the widget
|
42
40
|
|
43
41
|
Args:
|
@@ -47,7 +45,7 @@ class Alignment1D(BECWidget, QWidget):
|
|
47
45
|
gui_id: GUI ID.
|
48
46
|
"""
|
49
47
|
super().__init__(client=client, gui_id=gui_id)
|
50
|
-
|
48
|
+
QMainWindow.__init__(self)
|
51
49
|
self.get_bec_shortcuts()
|
52
50
|
self._accent_colors = get_accent_colors()
|
53
51
|
self.ui_file = "alignment_1d.ui"
|
@@ -60,9 +58,7 @@ class Alignment1D(BECWidget, QWidget):
|
|
60
58
|
"""Initialise the UI from QT Designer file"""
|
61
59
|
current_path = os.path.dirname(__file__)
|
62
60
|
self.ui = UILoader(self).loader(os.path.join(current_path, self.ui_file))
|
63
|
-
|
64
|
-
layout.addWidget(self.ui)
|
65
|
-
self.setLayout(layout)
|
61
|
+
self.setCentralWidget(self.ui)
|
66
62
|
# Customize the plotting widget
|
67
63
|
self.waveform = self.ui.findChild(BECWaveformWidget, "bec_waveform_widget")
|
68
64
|
self._customise_bec_waveform_widget()
|
@@ -249,7 +245,7 @@ class Alignment1D(BECWidget, QWidget):
|
|
249
245
|
box.ui.position_indicator.setFixedHeight(20)
|
250
246
|
|
251
247
|
|
252
|
-
|
248
|
+
def main():
|
253
249
|
import sys
|
254
250
|
|
255
251
|
from qtpy.QtWidgets import QApplication # pylint: disable=ungrouped-imports
|
@@ -263,3 +259,7 @@ if __name__ == "__main__": # pragma: no cover
|
|
263
259
|
window = Alignment1D()
|
264
260
|
window.show()
|
265
261
|
sys.exit(app.exec_())
|
262
|
+
|
263
|
+
|
264
|
+
if __name__ == "__main__": # pragma: no cover
|
265
|
+
main()
|
@@ -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>
|
@@ -0,0 +1,84 @@
|
|
1
|
+
"""
|
2
|
+
Launcher for BEC GUI Applications
|
3
|
+
|
4
|
+
Application must be located in bec_widgets/applications ;
|
5
|
+
in order for the launcher to find the application, it has to be put in
|
6
|
+
a subdirectory with the same name as the main Python module:
|
7
|
+
|
8
|
+
/bec_widgets/applications
|
9
|
+
├── alignment
|
10
|
+
│ └── alignment_1d
|
11
|
+
│ └── alignment_1d.py
|
12
|
+
├── other_app
|
13
|
+
└── other_app.py
|
14
|
+
|
15
|
+
The tree above would contain 2 applications, alignment_1d and other_app.
|
16
|
+
|
17
|
+
The Python module for the application must have `if __name__ == "__main__":`
|
18
|
+
in order for the launcher to execute it (it is run with `python -m`).
|
19
|
+
"""
|
20
|
+
|
21
|
+
import argparse
|
22
|
+
import os
|
23
|
+
import sys
|
24
|
+
|
25
|
+
MODULE_PATH = os.path.dirname(__file__)
|
26
|
+
|
27
|
+
|
28
|
+
def find_apps(base_dir: str) -> list[str]:
|
29
|
+
matching_modules = []
|
30
|
+
|
31
|
+
for root, dirs, files in os.walk(base_dir):
|
32
|
+
parent_dir = os.path.basename(root)
|
33
|
+
|
34
|
+
for file in files:
|
35
|
+
if file.endswith(".py") and file != "__init__.py":
|
36
|
+
file_name_without_ext = os.path.splitext(file)[0]
|
37
|
+
|
38
|
+
if file_name_without_ext == parent_dir:
|
39
|
+
rel_path = os.path.relpath(root, base_dir)
|
40
|
+
module_path = rel_path.replace(os.sep, ".")
|
41
|
+
|
42
|
+
module_name = f"{module_path}.{file_name_without_ext}"
|
43
|
+
matching_modules.append((file_name_without_ext, module_name))
|
44
|
+
|
45
|
+
return matching_modules
|
46
|
+
|
47
|
+
|
48
|
+
def main():
|
49
|
+
parser = argparse.ArgumentParser(description="BEC application launcher")
|
50
|
+
|
51
|
+
parser.add_argument("-m", "--module", type=str, help="The module to run (string argument).")
|
52
|
+
|
53
|
+
# Add a positional argument for the module, which acts as a fallback if -m is not provided
|
54
|
+
parser.add_argument(
|
55
|
+
"positional_module",
|
56
|
+
nargs="?", # This makes the positional argument optional
|
57
|
+
help="Positional argument that is treated as module if -m is not specified.",
|
58
|
+
)
|
59
|
+
|
60
|
+
args = parser.parse_args()
|
61
|
+
# If the -m/--module is not provided, fallback to the positional argument
|
62
|
+
module = args.module if args.module else args.positional_module
|
63
|
+
|
64
|
+
if module:
|
65
|
+
for app_name, app_module in find_apps(MODULE_PATH):
|
66
|
+
if module in (app_name, app_module):
|
67
|
+
print("Starting:", app_name)
|
68
|
+
python_executable = sys.executable
|
69
|
+
|
70
|
+
# Replace the current process with the new Python module
|
71
|
+
os.execvp(
|
72
|
+
python_executable,
|
73
|
+
[python_executable, "-m", f"bec_widgets.applications.{app_module}"],
|
74
|
+
)
|
75
|
+
print(f"Error: cannot find application {module}")
|
76
|
+
|
77
|
+
# display list of apps
|
78
|
+
print("Available applications:")
|
79
|
+
for app, _ in find_apps(MODULE_PATH):
|
80
|
+
print(f" - {app}")
|
81
|
+
|
82
|
+
|
83
|
+
if __name__ == "__main__": # pragma: no cover
|
84
|
+
main()
|
@@ -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()
|
@@ -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()
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: bec_widgets
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.116.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
|
@@ -11,7 +11,7 @@ Classifier: Topic :: Scientific/Engineering
|
|
11
11
|
Requires-Python: >=3.10
|
12
12
|
Requires-Dist: bec-ipython-client>=2.21.4,~=2.21
|
13
13
|
Requires-Dist: bec-lib>=2.21.4,~=2.21
|
14
|
-
Requires-Dist: bec-qthemes>=0.
|
14
|
+
Requires-Dist: bec-qthemes>=0.7,~=0.7
|
15
15
|
Requires-Dist: black~=24.0
|
16
16
|
Requires-Dist: isort>=5.13.2,~=5.13
|
17
17
|
Requires-Dist: pydantic~=2.0
|
@@ -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=DwezLJ73Dy8TWJoB2mEOp647_bYDgEMHUE9uIdnFqqw,7458
|
6
6
|
LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
|
7
|
-
PKG-INFO,sha256=
|
7
|
+
PKG-INFO,sha256=12J8zuxFZTwxmh1zZ-EPkH5IxLUYqcNnuZBPfllp5oM,1334
|
8
8
|
README.md,sha256=Od69x-RS85Hph0-WwWACwal4yUd67XkEn4APEfHhHFw,2649
|
9
|
-
pyproject.toml,sha256=
|
9
|
+
pyproject.toml,sha256=dBR14TzlvqiKTvf8L1PHidntzgrXzcOjAEyKmd0zSTM,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
|
@@ -14,10 +14,11 @@ pyproject.toml,sha256=gXCxP3PKeyd1s1-icN5yGEyZ-dPmyHDpefkRVsaku10,2544
|
|
14
14
|
.gitlab/merge_request_templates/default.md,sha256=tfyFA0hRCsIunbLGSlGbxWBQFeB3USpsA3H7IvwQ5UY,715
|
15
15
|
bec_widgets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
16
16
|
bec_widgets/applications/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
17
|
+
bec_widgets/applications/bec_app.py,sha256=PptBknsnhWm5GSE-xBps4EAYP3f9i-q9YmUMROupnqQ,2801
|
17
18
|
bec_widgets/applications/alignment/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
18
19
|
bec_widgets/applications/alignment/alignment_1d/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
19
|
-
bec_widgets/applications/alignment/alignment_1d/alignment_1d.py,sha256=
|
20
|
-
bec_widgets/applications/alignment/alignment_1d/alignment_1d.ui,sha256=
|
20
|
+
bec_widgets/applications/alignment/alignment_1d/alignment_1d.py,sha256=eGqEXKVz4kSdaIBZAKfuI4pwYoLWwKyLjTY1eB31kgk,11200
|
21
|
+
bec_widgets/applications/alignment/alignment_1d/alignment_1d.ui,sha256=CQz0UAXhWI4As_dsgfZUqCtYoqEAgEJl7IZWP7YxA5I,28940
|
21
22
|
bec_widgets/assets/app_icons/BEC-General-App.png,sha256=hc2ktly53DZAbl_rE3cb-vdRa5gtdCmBEjfwm2y5P4g,447581
|
22
23
|
bec_widgets/assets/app_icons/alignment_1d.png,sha256=5VouaWieb4lVv3wUBNHaO5ovUW2Fk25aTKYQzOWy0mg,2071069
|
23
24
|
bec_widgets/assets/app_icons/bec_widgets_icon.png,sha256=K8dgGwIjalDh9PRHUsSQBqgdX7a00nM3igZdc20pkYM,1747017
|
@@ -44,6 +45,7 @@ bec_widgets/examples/plugin_example_pyside/tictactoe.py,sha256=s3rCurXloVcmMdzZi
|
|
44
45
|
bec_widgets/examples/plugin_example_pyside/tictactoeplugin.py,sha256=MFMwONn4EZ3V8DboEG4I3BXpURE9JDbKB7XTzzfZl5w,1978
|
45
46
|
bec_widgets/examples/plugin_example_pyside/tictactoetaskmenu.py,sha256=V6OVnBTS-60zjQ2FAs88Ldjm1MfoMROfiQZZu6Guav8,2379
|
46
47
|
bec_widgets/qt_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
48
|
+
bec_widgets/qt_utils/compact_popup.py,sha256=DQel3iVjRYn6C5cR33ADSPyZObuMWSKwJYbwudb0o1k,8474
|
47
49
|
bec_widgets/qt_utils/error_popups.py,sha256=y9gKKWaafp468ioHr96nBhf02ZpEgjDc-BAVOTWh-e8,7680
|
48
50
|
bec_widgets/qt_utils/palette_viewer.py,sha256=PGhJ-4XI0f7gNnC1djNgcIHYg6HDO6hPju4pfWj9rvg,6311
|
49
51
|
bec_widgets/qt_utils/redis_message_waiter.py,sha256=fvL_QgC0cTDv_FPJdRyp5AKjf401EJU4z3r38p47ydY,1745
|
@@ -83,12 +85,12 @@ bec_widgets/widgets/bec_progressbar/bec_progress_bar_plugin.py,sha256=b0b0F37Hrw
|
|
83
85
|
bec_widgets/widgets/bec_progressbar/bec_progressbar.py,sha256=kkmpe5o9RPOCIKKPp0jjfQORLT8XKW_e-ETEl5Zmltk,7980
|
84
86
|
bec_widgets/widgets/bec_progressbar/register_bec_progress_bar.py,sha256=ZcGLPYEwkrbSOpxQeuZJRRVV3yXvcFh133hnlKIQGKw,488
|
85
87
|
bec_widgets/widgets/bec_queue/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
86
|
-
bec_widgets/widgets/bec_queue/bec_queue.py,sha256=
|
88
|
+
bec_widgets/widgets/bec_queue/bec_queue.py,sha256=5_uhcstSnbcQ__SmkWRfomEvDfwaJv3vTetXUV6w7Eo,8585
|
87
89
|
bec_widgets/widgets/bec_queue/bec_queue.pyproject,sha256=VhoNmAv1DQUl9dg7dELyf5i4pZ5k65N3GnqOYiSwbQo,27
|
88
90
|
bec_widgets/widgets/bec_queue/bec_queue_plugin.py,sha256=cotVUNKphAXQAp6mWtKoyzJ-vyAnfd86tGf4yNp0CjU,1341
|
89
91
|
bec_widgets/widgets/bec_queue/register_bec_queue.py,sha256=XnwtUSa1asK1b80knKWodcyX9qJy4DnKsQL_FoDfZy4,463
|
90
92
|
bec_widgets/widgets/bec_status_box/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
91
|
-
bec_widgets/widgets/bec_status_box/bec_status_box.py,sha256=
|
93
|
+
bec_widgets/widgets/bec_status_box/bec_status_box.py,sha256=udxOoTqO_qVO08B8kmVzn6YmAMLsAZBOERdm18hZIUc,13272
|
92
94
|
bec_widgets/widgets/bec_status_box/bec_status_box.pyproject,sha256=JWtx3Csfn2h7ODtk10HtyBNLf6tFIqyU6g04rMWOO1U,32
|
93
95
|
bec_widgets/widgets/bec_status_box/bec_status_box_plugin.py,sha256=UmsXAmeHg7FRkzirOLBPi3LwbRbG75w8LglYt4jn6Fc,1412
|
94
96
|
bec_widgets/widgets/bec_status_box/register_bec_status_box.py,sha256=EiQITnkNw7IU7hE776wAeXro97eZd9XlsB9essgCebE,481
|
@@ -262,8 +264,8 @@ bec_widgets/widgets/website/register_website_widget.py,sha256=LIQJpV9uqcBiPR9cEA
|
|
262
264
|
bec_widgets/widgets/website/website.py,sha256=42pncCc_zI2eqeMArIurVmPUukRo5bTxa2h1Skah-io,3012
|
263
265
|
bec_widgets/widgets/website/website_widget.pyproject,sha256=scOiV3cV1_BjbzpPzy2N8rIJL5P2qIZz8ObTJ-Uvdtg,25
|
264
266
|
bec_widgets/widgets/website/website_widget_plugin.py,sha256=pz38_C2cZ0yvPPS02wdIPcmhFo_yiwUhflsASocAPQQ,1341
|
265
|
-
bec_widgets-0.
|
266
|
-
bec_widgets-0.
|
267
|
-
bec_widgets-0.
|
268
|
-
bec_widgets-0.
|
269
|
-
bec_widgets-0.
|
267
|
+
bec_widgets-0.116.0.dist-info/METADATA,sha256=12J8zuxFZTwxmh1zZ-EPkH5IxLUYqcNnuZBPfllp5oM,1334
|
268
|
+
bec_widgets-0.116.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
|
269
|
+
bec_widgets-0.116.0.dist-info/entry_points.txt,sha256=dItMzmwA1wizJ1Itx15qnfJ0ZzKVYFLVJ1voxT7K7D4,214
|
270
|
+
bec_widgets-0.116.0.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
|
271
|
+
bec_widgets-0.116.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.116.0"
|
8
8
|
description = "BEC Widgets"
|
9
9
|
requires-python = ">=3.10"
|
10
10
|
classifiers = [
|
@@ -19,7 +19,7 @@ dependencies = [
|
|
19
19
|
"isort~=5.13, >=5.13.2", # needed for bw-generate-cli
|
20
20
|
"pydantic~=2.0",
|
21
21
|
"pyqtgraph~=0.13",
|
22
|
-
"bec_qthemes~=0.
|
22
|
+
"bec_qthemes~=0.7, >=0.7",
|
23
23
|
"qtconsole~=5.5, >=5.5.1", # needed for jupyter console
|
24
24
|
"qtpy~=2.4",
|
25
25
|
"pyte", # needed for vt100 console
|
@@ -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"
|
@@ -48,6 +48,7 @@ Homepage = "https://gitlab.psi.ch/bec/bec_widgets"
|
|
48
48
|
bw-generate-cli = "bec_widgets.cli.generate_cli:main"
|
49
49
|
bec-gui-server = "bec_widgets.cli.server:main"
|
50
50
|
bec-designer = "bec_widgets.utils.bec_designer:main"
|
51
|
+
bec-app = "bec_widgets.applications.bec_app:main"
|
51
52
|
|
52
53
|
[tool.hatch.build.targets.wheel]
|
53
54
|
include = ["*"]
|
File without changes
|
File without changes
|