bec-widgets 0.82.2__py3-none-any.whl → 0.83.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.
- .gitlab-ci.yml +3 -0
- CHANGELOG.md +26 -28
- PKG-INFO +1 -1
- bec_widgets/utils/bec_connector.py +2 -0
- bec_widgets/utils/bec_widget.py +6 -0
- bec_widgets/utils/generate_designer_plugin.py +6 -5
- bec_widgets/utils/reference_utils.py +92 -0
- bec_widgets/widgets/console/console.py +1 -1
- bec_widgets/widgets/device_box/__init__.py +0 -0
- bec_widgets/widgets/device_box/device_box.py +197 -0
- bec_widgets/widgets/device_box/device_box.pyproject +1 -0
- bec_widgets/widgets/device_box/device_box.ui +179 -0
- bec_widgets/widgets/device_box/device_box_plugin.py +54 -0
- bec_widgets/widgets/device_box/register_device_box.py +15 -0
- bec_widgets/widgets/figure/figure.py +3 -3
- bec_widgets/widgets/position_indicator/position_indicator.py +71 -0
- bec_widgets/widgets/position_indicator/position_indicator.pyproject +1 -0
- bec_widgets/widgets/position_indicator/position_indicator_plugin.py +54 -0
- bec_widgets/widgets/position_indicator/register_position_indicator.py +17 -0
- bec_widgets/widgets/spinner/__init__.py +0 -0
- bec_widgets/widgets/spinner/register_spinner_widget.py +15 -0
- bec_widgets/widgets/spinner/spinner.py +85 -0
- bec_widgets/widgets/spinner/spinner_widget.pyproject +1 -0
- bec_widgets/widgets/spinner/spinner_widget_plugin.py +54 -0
- bec_widgets/widgets/vscode/vscode.py +0 -14
- bec_widgets/widgets/website/website.py +1 -1
- {bec_widgets-0.82.2.dist-info → bec_widgets-0.83.0.dist-info}/METADATA +1 -1
- {bec_widgets-0.82.2.dist-info → bec_widgets-0.83.0.dist-info}/RECORD +40 -18
- pyproject.toml +1 -1
- tests/references/SpinnerWidget/SpinnerWidget_darwin.png +0 -0
- tests/references/SpinnerWidget/SpinnerWidget_linux.png +0 -0
- tests/references/SpinnerWidget/SpinnerWidget_started_darwin.png +0 -0
- tests/references/SpinnerWidget/SpinnerWidget_started_linux.png +0 -0
- tests/unit_tests/client_mocks.py +9 -1
- tests/unit_tests/test_device_box.py +98 -0
- tests/unit_tests/test_spinner.py +30 -0
- tests/unit_tests/test_vscode_widget.py +27 -32
- {bec_widgets-0.82.2.dist-info → bec_widgets-0.83.0.dist-info}/WHEEL +0 -0
- {bec_widgets-0.82.2.dist-info → bec_widgets-0.83.0.dist-info}/entry_points.txt +0 -0
- {bec_widgets-0.82.2.dist-info → bec_widgets-0.83.0.dist-info}/licenses/LICENSE +0 -0
@@ -830,6 +830,6 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
|
|
830
830
|
widget_class=self.__class__.__name__, gui_id=self.gui_id, theme=theme
|
831
831
|
)
|
832
832
|
|
833
|
-
def cleanup(self):
|
834
|
-
|
835
|
-
|
833
|
+
# def cleanup(self):
|
834
|
+
# self.clear_all()
|
835
|
+
# super().cleanup()
|
@@ -0,0 +1,71 @@
|
|
1
|
+
from qtpy.QtCore import Qt, Slot
|
2
|
+
from qtpy.QtGui import QPainter, QPen
|
3
|
+
from qtpy.QtWidgets import QWidget
|
4
|
+
|
5
|
+
|
6
|
+
class PositionIndicator(QWidget):
|
7
|
+
|
8
|
+
def __init__(self, parent=None):
|
9
|
+
super().__init__(parent)
|
10
|
+
self.position = 0.5
|
11
|
+
self.min_value = 0
|
12
|
+
self.max_value = 100
|
13
|
+
self.scaling_factor = 0.5
|
14
|
+
self.setMinimumHeight(10)
|
15
|
+
|
16
|
+
def set_range(self, min_value, max_value):
|
17
|
+
self.min_value = min_value
|
18
|
+
self.max_value = max_value
|
19
|
+
|
20
|
+
@Slot(float)
|
21
|
+
def on_position_update(self, position: float):
|
22
|
+
self.position = position
|
23
|
+
self.update()
|
24
|
+
|
25
|
+
def paintEvent(self, event):
|
26
|
+
painter = QPainter(self)
|
27
|
+
painter.setRenderHint(QPainter.Antialiasing)
|
28
|
+
|
29
|
+
width = self.width()
|
30
|
+
height = self.height()
|
31
|
+
|
32
|
+
# Draw horizontal line
|
33
|
+
painter.setPen(Qt.black)
|
34
|
+
painter.drawLine(0, height // 2, width, height // 2)
|
35
|
+
|
36
|
+
# Draw shorter vertical line at the current position
|
37
|
+
x_pos = int(self.position * width)
|
38
|
+
painter.setPen(QPen(Qt.red, 2))
|
39
|
+
short_line_height = int(height * self.scaling_factor)
|
40
|
+
painter.drawLine(
|
41
|
+
x_pos,
|
42
|
+
(height // 2) - (short_line_height // 2),
|
43
|
+
x_pos,
|
44
|
+
(height // 2) + (short_line_height // 2),
|
45
|
+
)
|
46
|
+
|
47
|
+
# Draw thicker vertical lines at the ends
|
48
|
+
end_line_pen = QPen(Qt.blue, 5)
|
49
|
+
painter.setPen(end_line_pen)
|
50
|
+
painter.drawLine(0, 0, 0, height)
|
51
|
+
painter.drawLine(width - 1, 0, width - 1, height)
|
52
|
+
|
53
|
+
|
54
|
+
if __name__ == "__main__":
|
55
|
+
from qtpy.QtWidgets import QApplication, QSlider, QVBoxLayout
|
56
|
+
|
57
|
+
app = QApplication([])
|
58
|
+
|
59
|
+
position_indicator = PositionIndicator()
|
60
|
+
slider = QSlider(Qt.Horizontal)
|
61
|
+
slider.valueChanged.connect(lambda value: position_indicator.on_position_update(value / 100))
|
62
|
+
|
63
|
+
layout = QVBoxLayout()
|
64
|
+
layout.addWidget(position_indicator)
|
65
|
+
layout.addWidget(slider)
|
66
|
+
|
67
|
+
widget = QWidget()
|
68
|
+
widget.setLayout(layout)
|
69
|
+
widget.show()
|
70
|
+
|
71
|
+
app.exec_()
|
@@ -0,0 +1 @@
|
|
1
|
+
{'files': ['position_indicator.py']}
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# Copyright (C) 2022 The Qt Company Ltd.
|
2
|
+
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
3
|
+
|
4
|
+
from qtpy.QtDesigner import QDesignerCustomWidgetInterface
|
5
|
+
from qtpy.QtGui import QIcon
|
6
|
+
|
7
|
+
from bec_widgets.widgets.position_indicator.position_indicator import PositionIndicator
|
8
|
+
|
9
|
+
DOM_XML = """
|
10
|
+
<ui language='c++'>
|
11
|
+
<widget class='PositionIndicator' name='position_indicator'>
|
12
|
+
</widget>
|
13
|
+
</ui>
|
14
|
+
"""
|
15
|
+
|
16
|
+
|
17
|
+
class PositionIndicatorPlugin(QDesignerCustomWidgetInterface): # pragma: no cover
|
18
|
+
def __init__(self):
|
19
|
+
super().__init__()
|
20
|
+
self._form_editor = None
|
21
|
+
|
22
|
+
def createWidget(self, parent):
|
23
|
+
t = PositionIndicator(parent)
|
24
|
+
return t
|
25
|
+
|
26
|
+
def domXml(self):
|
27
|
+
return DOM_XML
|
28
|
+
|
29
|
+
def group(self):
|
30
|
+
return ""
|
31
|
+
|
32
|
+
def icon(self):
|
33
|
+
return QIcon()
|
34
|
+
|
35
|
+
def includeFile(self):
|
36
|
+
return "position_indicator"
|
37
|
+
|
38
|
+
def initialize(self, form_editor):
|
39
|
+
self._form_editor = form_editor
|
40
|
+
|
41
|
+
def isContainer(self):
|
42
|
+
return False
|
43
|
+
|
44
|
+
def isInitialized(self):
|
45
|
+
return self._form_editor is not None
|
46
|
+
|
47
|
+
def name(self):
|
48
|
+
return "PositionIndicator"
|
49
|
+
|
50
|
+
def toolTip(self):
|
51
|
+
return "PositionIndicator"
|
52
|
+
|
53
|
+
def whatsThis(self):
|
54
|
+
return self.toolTip()
|
@@ -0,0 +1,17 @@
|
|
1
|
+
def main(): # pragma: no cover
|
2
|
+
from qtpy import PYSIDE6
|
3
|
+
|
4
|
+
if not PYSIDE6:
|
5
|
+
print("PYSIDE6 is not available in the environment. Cannot patch designer.")
|
6
|
+
return
|
7
|
+
from PySide6.QtDesigner import QPyDesignerCustomWidgetCollection
|
8
|
+
|
9
|
+
from bec_widgets.widgets.position_indicator.position_indicator_plugin import (
|
10
|
+
PositionIndicatorPlugin,
|
11
|
+
)
|
12
|
+
|
13
|
+
QPyDesignerCustomWidgetCollection.addCustomWidget(PositionIndicatorPlugin())
|
14
|
+
|
15
|
+
|
16
|
+
if __name__ == "__main__": # pragma: no cover
|
17
|
+
main()
|
File without changes
|
@@ -0,0 +1,15 @@
|
|
1
|
+
def main(): # pragma: no cover
|
2
|
+
from qtpy import PYSIDE6
|
3
|
+
|
4
|
+
if not PYSIDE6:
|
5
|
+
print("PYSIDE6 is not available in the environment. Cannot patch designer.")
|
6
|
+
return
|
7
|
+
from PySide6.QtDesigner import QPyDesignerCustomWidgetCollection
|
8
|
+
|
9
|
+
from bec_widgets.widgets.spinner.spinner_widget_plugin import SpinnerWidgetPlugin
|
10
|
+
|
11
|
+
QPyDesignerCustomWidgetCollection.addCustomWidget(SpinnerWidgetPlugin())
|
12
|
+
|
13
|
+
|
14
|
+
if __name__ == "__main__": # pragma: no cover
|
15
|
+
main()
|
@@ -0,0 +1,85 @@
|
|
1
|
+
import sys
|
2
|
+
|
3
|
+
import numpy as np
|
4
|
+
import qdarktheme
|
5
|
+
from qtpy.QtCore import QRect, Qt, QTimer
|
6
|
+
from qtpy.QtGui import QColor, QPainter, QPen
|
7
|
+
from qtpy.QtWidgets import QApplication, QMainWindow, QWidget
|
8
|
+
|
9
|
+
|
10
|
+
def ease_in_out_sine(t):
|
11
|
+
return 1 - np.sin(np.pi * t)
|
12
|
+
|
13
|
+
|
14
|
+
class SpinnerWidget(QWidget):
|
15
|
+
def __init__(self, parent=None):
|
16
|
+
super().__init__(parent)
|
17
|
+
|
18
|
+
self.angle = 0
|
19
|
+
self.timer = QTimer(self)
|
20
|
+
self.timer.timeout.connect(self.rotate)
|
21
|
+
self.time = 0
|
22
|
+
self.duration = 50
|
23
|
+
self.speed = 50
|
24
|
+
self._started = False
|
25
|
+
|
26
|
+
def start(self):
|
27
|
+
if self._started:
|
28
|
+
return
|
29
|
+
self.timer.start(self.speed)
|
30
|
+
self._started = True
|
31
|
+
|
32
|
+
def stop(self):
|
33
|
+
if not self._started:
|
34
|
+
return
|
35
|
+
self.timer.stop()
|
36
|
+
self._started = False
|
37
|
+
self.update()
|
38
|
+
|
39
|
+
def rotate(self):
|
40
|
+
self.time = (self.time + 1) % self.duration
|
41
|
+
t = self.time / self.duration
|
42
|
+
easing_value = ease_in_out_sine(t)
|
43
|
+
self.angle -= (20 * easing_value) % 360 + 10
|
44
|
+
self.update()
|
45
|
+
|
46
|
+
def paintEvent(self, event):
|
47
|
+
painter = QPainter(self)
|
48
|
+
painter.setRenderHint(QPainter.Antialiasing)
|
49
|
+
size = min(self.width(), self.height())
|
50
|
+
rect = QRect(0, 0, size, size)
|
51
|
+
|
52
|
+
background_color = QColor(200, 200, 200, 50)
|
53
|
+
line_width = 5
|
54
|
+
|
55
|
+
color_palette = qdarktheme.load_palette()
|
56
|
+
|
57
|
+
color = QColor(color_palette.accent().color())
|
58
|
+
|
59
|
+
rect.adjust(line_width, line_width, -line_width, -line_width)
|
60
|
+
|
61
|
+
# Background arc
|
62
|
+
painter.setPen(QPen(background_color, line_width, Qt.SolidLine))
|
63
|
+
adjusted_rect = QRect(rect.left(), rect.top(), rect.width(), rect.height())
|
64
|
+
painter.drawArc(adjusted_rect, 0, 360 * 16)
|
65
|
+
|
66
|
+
if self._started:
|
67
|
+
# Foreground arc
|
68
|
+
pen = QPen(color, line_width, Qt.SolidLine)
|
69
|
+
pen.setCapStyle(Qt.RoundCap)
|
70
|
+
painter.setPen(pen)
|
71
|
+
proportion = 1 / 4
|
72
|
+
angle_span = int(proportion * 360 * 16)
|
73
|
+
angle_span += angle_span * ease_in_out_sine(self.time / self.duration)
|
74
|
+
painter.drawArc(adjusted_rect, self.angle * 16, int(angle_span))
|
75
|
+
painter.end()
|
76
|
+
|
77
|
+
|
78
|
+
if __name__ == "__main__": # pragma: no cover
|
79
|
+
app = QApplication(sys.argv)
|
80
|
+
window = QMainWindow()
|
81
|
+
widget = SpinnerWidget()
|
82
|
+
widget.start()
|
83
|
+
window.setCentralWidget(widget)
|
84
|
+
window.show()
|
85
|
+
sys.exit(app.exec())
|
@@ -0,0 +1 @@
|
|
1
|
+
{'files': ['spinner.py']}
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# Copyright (C) 2022 The Qt Company Ltd.
|
2
|
+
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
3
|
+
|
4
|
+
from qtpy.QtDesigner import QDesignerCustomWidgetInterface
|
5
|
+
from qtpy.QtGui import QIcon
|
6
|
+
|
7
|
+
from bec_widgets.widgets.spinner.spinner import SpinnerWidget
|
8
|
+
|
9
|
+
DOM_XML = """
|
10
|
+
<ui language='c++'>
|
11
|
+
<widget class='SpinnerWidget' name='spinner_widget'>
|
12
|
+
</widget>
|
13
|
+
</ui>
|
14
|
+
"""
|
15
|
+
|
16
|
+
|
17
|
+
class SpinnerWidgetPlugin(QDesignerCustomWidgetInterface): # pragma: no cover
|
18
|
+
def __init__(self):
|
19
|
+
super().__init__()
|
20
|
+
self._form_editor = None
|
21
|
+
|
22
|
+
def createWidget(self, parent):
|
23
|
+
t = SpinnerWidget(parent)
|
24
|
+
return t
|
25
|
+
|
26
|
+
def domXml(self):
|
27
|
+
return DOM_XML
|
28
|
+
|
29
|
+
def group(self):
|
30
|
+
return ""
|
31
|
+
|
32
|
+
def icon(self):
|
33
|
+
return QIcon()
|
34
|
+
|
35
|
+
def includeFile(self):
|
36
|
+
return "spinner_widget"
|
37
|
+
|
38
|
+
def initialize(self, form_editor):
|
39
|
+
self._form_editor = form_editor
|
40
|
+
|
41
|
+
def isContainer(self):
|
42
|
+
return False
|
43
|
+
|
44
|
+
def isInitialized(self):
|
45
|
+
return self._form_editor is not None
|
46
|
+
|
47
|
+
def name(self):
|
48
|
+
return "SpinnerWidget"
|
49
|
+
|
50
|
+
def toolTip(self):
|
51
|
+
return "SpinnerWidget"
|
52
|
+
|
53
|
+
def whatsThis(self):
|
54
|
+
return self.toolTip()
|
@@ -49,13 +49,6 @@ class VSCodeEditor(WebsiteWidget):
|
|
49
49
|
break
|
50
50
|
self.set_url(self._url)
|
51
51
|
|
52
|
-
def closeEvent(self, event):
|
53
|
-
"""
|
54
|
-
Hook for the close event to terminate the server.
|
55
|
-
"""
|
56
|
-
self.cleanup_vscode()
|
57
|
-
super().closeEvent(event)
|
58
|
-
|
59
52
|
def cleanup_vscode(self):
|
60
53
|
"""
|
61
54
|
Cleanup the VSCode editor.
|
@@ -72,13 +65,6 @@ class VSCodeEditor(WebsiteWidget):
|
|
72
65
|
self.cleanup_vscode()
|
73
66
|
return super().cleanup()
|
74
67
|
|
75
|
-
def close(self):
|
76
|
-
"""
|
77
|
-
Close the widget.
|
78
|
-
"""
|
79
|
-
self.cleanup_vscode()
|
80
|
-
return super().close()
|
81
|
-
|
82
68
|
|
83
69
|
if __name__ == "__main__": # pragma: no cover
|
84
70
|
import sys
|
@@ -1,12 +1,12 @@
|
|
1
1
|
.gitignore,sha256=cMQ1MLmnoR88aMCCJwUyfoTnufzl4-ckmHtlFUqHcT4,3253
|
2
|
-
.gitlab-ci.yml,sha256=
|
2
|
+
.gitlab-ci.yml,sha256=zvb4A6QI5lQTsdfI5nPPL-tUNfcrz__SQjxW03QZ5Ek,8204
|
3
3
|
.pylintrc,sha256=eeY8YwSI74oFfq6IYIbCqnx3Vk8ZncKaatv96n_Y8Rs,18544
|
4
4
|
.readthedocs.yaml,sha256=aSOc277LqXcsTI6lgvm_JY80lMlr69GbPKgivua2cS0,603
|
5
|
-
CHANGELOG.md,sha256=
|
5
|
+
CHANGELOG.md,sha256=yrNwpjAjIHr7MeZHZe2O0EkihwIB__p1ZrFzl16iUqI,6680
|
6
6
|
LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
|
7
|
-
PKG-INFO,sha256=
|
7
|
+
PKG-INFO,sha256=xSeHtjGGoakyD7GAov5Syu1U4lMGeuIPyORPJeEfz9o,1309
|
8
8
|
README.md,sha256=Od69x-RS85Hph0-WwWACwal4yUd67XkEn4APEfHhHFw,2649
|
9
|
-
pyproject.toml,sha256=
|
9
|
+
pyproject.toml,sha256=t0CTeL_fv-YSLp6OaG1DgQdwsSFZrYKnIzs9jFl-mNk,2358
|
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
|
@@ -38,18 +38,19 @@ bec_widgets/qt_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hS
|
|
38
38
|
bec_widgets/qt_utils/settings_dialog.py,sha256=rR_Zk4RGTnI4dz5OEzCc13lVpxlOKuwOf4_7wqXSbRw,3373
|
39
39
|
bec_widgets/qt_utils/toolbar.py,sha256=r6H4A8_3s2AItmdV8JS9UMSM4hV8Fx_162grYL2Pwzw,2111
|
40
40
|
bec_widgets/utils/__init__.py,sha256=1930ji1Jj6dVuY81Wd2kYBhHYNV-2R0bN_L4o9zBj1U,533
|
41
|
-
bec_widgets/utils/bec_connector.py,sha256=
|
41
|
+
bec_widgets/utils/bec_connector.py,sha256=NypWbIrqb2ls3SIpflM6KihidV9fkroiJu2tQk6KwOA,9604
|
42
42
|
bec_widgets/utils/bec_designer.py,sha256=ak3G8FdojUPjVBBwdPXw7tN5P2Uxr-SSoQt394jXeAA,4308
|
43
43
|
bec_widgets/utils/bec_dispatcher.py,sha256=dghOw63Ql6rQ-zH1ZaYU6kT9Dg5kNDcZwEdu2YPBJeU,6150
|
44
44
|
bec_widgets/utils/bec_table.py,sha256=nA2b8ukSeUfquFMAxGrUVOqdrzMoDYD6O_4EYbOG2zk,717
|
45
|
-
bec_widgets/utils/bec_widget.py,sha256=
|
45
|
+
bec_widgets/utils/bec_widget.py,sha256=eC7jhCqyABDf_wGbM6cCdtSF4__rpnVs2Ir1XzGHrCs,238
|
46
46
|
bec_widgets/utils/colors.py,sha256=CP_lwj757CpwdVhWSfdNEXKFCEVVVF48DizD2WJKSwI,9759
|
47
47
|
bec_widgets/utils/container_utils.py,sha256=m3VUyAYmSWkEwApP9tBvKxPYVtc2kHw4toxIpMryJy4,1495
|
48
48
|
bec_widgets/utils/crosshair.py,sha256=SubY4FQCI6vUKsmMYGKHR7uYdGQJ6vhoYLuC1XlKS9I,9626
|
49
49
|
bec_widgets/utils/entry_validator.py,sha256=3skJIsUwTYicT76AMHm_M78RiWtUgyD2zb-Rxo2HdHQ,1313
|
50
|
-
bec_widgets/utils/generate_designer_plugin.py,sha256=
|
50
|
+
bec_widgets/utils/generate_designer_plugin.py,sha256=JlkJo0Iu5dA_7HQ0silT8kLnYHhKZ8fKUFeysm1k0l0,5878
|
51
51
|
bec_widgets/utils/layout_manager.py,sha256=H0nKsIMaPxRkof1MEXlSmW6w1dFxA6astaGzf4stI84,4727
|
52
52
|
bec_widgets/utils/plugin_utils.py,sha256=njvVdvF-AR47Yn80ntpvFldEvLuFx9GV-qEX4p_n4AI,5263
|
53
|
+
bec_widgets/utils/reference_utils.py,sha256=8pq06TOvZBZdim0G6hvPJXzVDib7ve4o-Ptvfp563nk,2859
|
53
54
|
bec_widgets/utils/rpc_decorator.py,sha256=pIvtqySQLnuS7l2Ti_UAe4WX7CRivZnsE5ZdKAihxh0,479
|
54
55
|
bec_widgets/utils/thread_checker.py,sha256=rDNuA3X6KQyA7JPb67mccTg0z8YkInynLAENQDQpbuE,1607
|
55
56
|
bec_widgets/utils/ui_loader.py,sha256=9C4DkMIM8PEGXs2LmbZMyLVt38EIO9-T9C2UnK2SAvE,4882
|
@@ -78,7 +79,13 @@ bec_widgets/widgets/color_button/color_button.pyproject,sha256=LUYF4VkDOB4ttVe7Y
|
|
78
79
|
bec_widgets/widgets/color_button/color_button_plugin.py,sha256=CvO3L6r8pBd-0DNuqjQ7uKF9u1mU6xFs23sS_dsj4tw,1256
|
79
80
|
bec_widgets/widgets/color_button/register_color_button.py,sha256=ZAx3t7G2VI2S-1qcEof31Xi9O0X8deLeZNgS651L1JI,475
|
80
81
|
bec_widgets/widgets/color_button/assets/color_button.png,sha256=dkjgGHSdxu98nM68O16fGpxBjxkkeLN8iu9M_8i5-NY,5618
|
81
|
-
bec_widgets/widgets/console/console.py,sha256=
|
82
|
+
bec_widgets/widgets/console/console.py,sha256=IW1OerycmS-cm8CKGFig44Qye8mxsmVcKvLHAc3lXco,17845
|
83
|
+
bec_widgets/widgets/device_box/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
84
|
+
bec_widgets/widgets/device_box/device_box.py,sha256=c-g31zzO4XuQgcR2qnZiRRYllYIMWtx1lGZXYRSxGiI,6922
|
85
|
+
bec_widgets/widgets/device_box/device_box.pyproject,sha256=jtwvhaySJRdnuV99mEZT3htmWKVLphFeetEW4al7s-o,28
|
86
|
+
bec_widgets/widgets/device_box/device_box.ui,sha256=z7j60J4ZKYjH9eyHl6FnZ_Z8lkdq1LQftxveSZQ6g_w,4865
|
87
|
+
bec_widgets/widgets/device_box/device_box_plugin.py,sha256=n7l3OIKqtQGsL86ygDekb0wb4bBySJXMUo58eTtKIdQ,1212
|
88
|
+
bec_widgets/widgets/device_box/register_device_box.py,sha256=K7Hx4FIQDXasejaw6njwkFkkkwk63Smm6pHoOEdLWPw,467
|
82
89
|
bec_widgets/widgets/device_combobox/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
83
90
|
bec_widgets/widgets/device_combobox/device_combobox.py,sha256=L6hPOk3LkTy9U_HRdU7bvqCH1L1Y_BuPYTTfl1eqShg,2824
|
84
91
|
bec_widgets/widgets/device_combobox/device_combobox.pyproject,sha256=wI2eXR5ky_IM9-BCHJnH_9CEqYcZwIuLcgitSEr8OJU,40
|
@@ -95,7 +102,7 @@ bec_widgets/widgets/dock/__init__.py,sha256=B7foHt02gnhM7mFksa7GJVwT7n0j_JvYDCt6
|
|
95
102
|
bec_widgets/widgets/dock/dock.py,sha256=joymi8NRoIuzuugUj9ccF9e1m57HwLQhhMmjaWiwTnM,7597
|
96
103
|
bec_widgets/widgets/dock/dock_area.py,sha256=WKIt61v7w2YXahfIL4nddWHPfpTpw52uphX4QCbS3q0,7913
|
97
104
|
bec_widgets/widgets/figure/__init__.py,sha256=3hGx_KOV7QHCYAV06aNuUgKq4QIYCjUTad-DrwkUaBM,44
|
98
|
-
bec_widgets/widgets/figure/figure.py,sha256=
|
105
|
+
bec_widgets/widgets/figure/figure.py,sha256=lkU5mGtgi2_kF1FGrz_CYH7aifXxtan5xWNAdl3raXw,32054
|
99
106
|
bec_widgets/widgets/figure/plots/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
100
107
|
bec_widgets/widgets/figure/plots/axis_settings.py,sha256=RMvbPgu8r1bk8zZz49hkUSHmcqRdw19zrsfLHcgDUIc,2261
|
101
108
|
bec_widgets/widgets/figure/plots/axis_settings.ui,sha256=zMKZK6lH_3KJGO4RA_paXAH7UzZJ4Snlil3MK4pK3L8,11589
|
@@ -124,12 +131,21 @@ bec_widgets/widgets/motor_map/motor_map_dialog/__init__.py,sha256=47DEQpj8HBSa-_
|
|
124
131
|
bec_widgets/widgets/motor_map/motor_map_dialog/motor_map_settings.py,sha256=terJ5NHRzAsiUwdqg-hTbkQ5gadnRT0Ol0_Fm66kPF4,2011
|
125
132
|
bec_widgets/widgets/motor_map/motor_map_dialog/motor_map_settings.ui,sha256=nv5vPftt6vcIl60OOZLRvwD29rdHVWOoGmz168BnwKw,2685
|
126
133
|
bec_widgets/widgets/motor_map/motor_map_dialog/motor_map_toolbar.py,sha256=R6pmxhB_1ouc6f6cNQQvbxTHb3Ko3K_gTGs5WIYgnRI,2194
|
134
|
+
bec_widgets/widgets/position_indicator/position_indicator.py,sha256=QVlWvs_RvEJe5IMxGYCpi-CXYF7vFeMqEMFCs6u5NGc,2020
|
135
|
+
bec_widgets/widgets/position_indicator/position_indicator.pyproject,sha256=s0JEf5YkpMag19ddFSYeRZ8erBau7erO3bqw05YrTyg,36
|
136
|
+
bec_widgets/widgets/position_indicator/position_indicator_plugin.py,sha256=h9EQU4t6KdKVAZh5ILalpl1K8b7JMHf-2AFYREej2-w,1241
|
137
|
+
bec_widgets/widgets/position_indicator/register_position_indicator.py,sha256=OZNiMgM_80TPSAXK_0hXAkne4vUh8DGvh_OdpOiMpwI,516
|
127
138
|
bec_widgets/widgets/ring_progress_bar/__init__.py,sha256=_uoJKnDM2YAeUBfwc5WLbIHSJj7zm_FAurSKP3WRaCw,47
|
128
139
|
bec_widgets/widgets/ring_progress_bar/ring.py,sha256=19zFj-6ZrIPLXYqvs5EPcrmDWnfnSLlEOmzJffL4d3A,11241
|
129
140
|
bec_widgets/widgets/ring_progress_bar/ring_progress_bar.py,sha256=sU4Dur2XzBVfDYAYazI6pjOZOhzggoQIuc9VD3PWgac,24073
|
130
141
|
bec_widgets/widgets/scan_control/__init__.py,sha256=IOfHl15vxb_uC6KN62-PeUzbBha_vQyqkkXbJ2HU674,38
|
131
142
|
bec_widgets/widgets/scan_control/scan_control.py,sha256=EHibpeK8vpG6rlg8zhvDDz8GDUzDmvhYH0aX7-Xo4m8,7689
|
132
143
|
bec_widgets/widgets/scan_control/scan_group_box.py,sha256=wrrJLfI0apfll0NKpqM8ymlbl5NaqA9cKNgyfVdYR00,7420
|
144
|
+
bec_widgets/widgets/spinner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
145
|
+
bec_widgets/widgets/spinner/register_spinner_widget.py,sha256=_zCPjLh4M7NTSHP1Atdn6yu33zJ3LJkcBy3KOJ5eSVY,476
|
146
|
+
bec_widgets/widgets/spinner/spinner.py,sha256=aWr0NnJVISwlBXGMnModJDwVNF4Xr01mDegGev29xPo,2465
|
147
|
+
bec_widgets/widgets/spinner/spinner_widget.pyproject,sha256=zzLajGB3DTgVnrSqMey2jRpBlxTq9cBXZL9tWJCKe-I,25
|
148
|
+
bec_widgets/widgets/spinner/spinner_widget_plugin.py,sha256=ZcG1QIwpbriapM5ZrR4gQ-WA2a7ARhsstk8EIY-OGTU,1187
|
133
149
|
bec_widgets/widgets/stop_button/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
134
150
|
bec_widgets/widgets/stop_button/register_stop_button.py,sha256=U7r3fEOH-uPhAQI-nTituHXDDXDWR4JQZ7_vD6b_dfM,471
|
135
151
|
bec_widgets/widgets/stop_button/stop_button.py,sha256=icJQT1k5G_nvdHWZZkGEZVQupt-mWd2viK8zYg5B5dI,793
|
@@ -144,9 +160,9 @@ bec_widgets/widgets/toggle/toggle.py,sha256=JzCGYoyHBrlBWCoyL94QX4zSLyEwWbCNHMeg
|
|
144
160
|
bec_widgets/widgets/toggle/toggle_switch.pyproject,sha256=Msa-AS5H5XlqW65r8GlX2AxD8FnFnDyDgGnbKcXqKOw,24
|
145
161
|
bec_widgets/widgets/toggle/toggle_switch_plugin.py,sha256=8e8JjUx6T5CIx7ixWLwVdT9JOJTbQ8aWwd3_9VAc_Mw,1177
|
146
162
|
bec_widgets/widgets/vscode/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
147
|
-
bec_widgets/widgets/vscode/vscode.py,sha256=
|
163
|
+
bec_widgets/widgets/vscode/vscode.py,sha256=yV1D9PK2IYomq9yYfwqUOrZGIeBwMnNuBfXxBc2M8Qc,2231
|
148
164
|
bec_widgets/widgets/website/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
149
|
-
bec_widgets/widgets/website/website.py,sha256
|
165
|
+
bec_widgets/widgets/website/website.py,sha256=-5JG2dh7Ftw9xv8I4p08TxjaRzaql9XZDiv1iQOIFsU,1726
|
150
166
|
docs/Makefile,sha256=i2WHuFlgfyAPEW4ssEP8NY4cOibDJrVjvzSEU8_Ggwc,634
|
151
167
|
docs/conf.py,sha256=HxLxupNGu0Smhwn57g1kFdjZzFuaWVREgRJKhT1zi2k,2464
|
152
168
|
docs/index.md,sha256=8ZCgaLIbJsYvt-jwi--QxsNwnK4-k3rejIeOOLclG40,1101
|
@@ -202,8 +218,12 @@ tests/end-2-end/test_bec_dock_rpc_e2e.py,sha256=uDhauuLEWg9Baf3N1KSeq6HPUWtuU6a9
|
|
202
218
|
tests/end-2-end/test_bec_figure_rpc_e2e.py,sha256=mjg29huqTivLnukG_XyoMtjOy2P_7JACIhMEzahLXb8,6601
|
203
219
|
tests/end-2-end/test_rpc_register_e2e.py,sha256=blhMiW7HVHX1kGm5dg8Sv0PeCuJ0gnBz3evznQFz_B8,1619
|
204
220
|
tests/end-2-end/test_scan_control_e2e.py,sha256=u7oLgFyltkMW2apSZKDukMIXvYrbhHrU32p4mBdn8VE,2276
|
221
|
+
tests/references/SpinnerWidget/SpinnerWidget_darwin.png,sha256=-Tf5x0xY0pb-8sXH6Pk8cZL5PAxZ4vMR5RgyGCxisM4,9490
|
222
|
+
tests/references/SpinnerWidget/SpinnerWidget_linux.png,sha256=-Tf5x0xY0pb-8sXH6Pk8cZL5PAxZ4vMR5RgyGCxisM4,9490
|
223
|
+
tests/references/SpinnerWidget/SpinnerWidget_started_darwin.png,sha256=wPc65MrSSKJib2aBlPI20mBE-zfamOh-SORGRD27dhQ,14773
|
224
|
+
tests/references/SpinnerWidget/SpinnerWidget_started_linux.png,sha256=gE1L3nVuypmsW8vcnV9kX4mDgQGGXYjiEIYiRifr5DM,15265
|
205
225
|
tests/unit_tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
206
|
-
tests/unit_tests/client_mocks.py,sha256=
|
226
|
+
tests/unit_tests/client_mocks.py,sha256=_gtf12kTxmwaXKwSOG5Cc0dqVEY1PHi-hmqdTdLhLTk,4752
|
207
227
|
tests/unit_tests/conftest.py,sha256=KrnktXPWmZhnKNue-xGWOLD1XGEvdz9Vf7V2eO3XQ3A,596
|
208
228
|
tests/unit_tests/test_bec_connector.py,sha256=zGDfNHwLFZTbpyX6-yc7Pwzr2jWO_HGZ8T4NFCNo4IE,2444
|
209
229
|
tests/unit_tests/test_bec_dispatcher.py,sha256=rYPiRizHaswhGZw55IBMneDFxmPiCCLAZQBqjEkpdyY,3992
|
@@ -216,6 +236,7 @@ tests/unit_tests/test_bec_status_box.py,sha256=gZdjyy9DNuUP9UwleTLj2Dp5HUImiqnkH
|
|
216
236
|
tests/unit_tests/test_client_utils.py,sha256=CBdWIVJ_UiyFzTJnX3XJm4PGw2uXhFvRCP_Y9ifckbw,2630
|
217
237
|
tests/unit_tests/test_color_validation.py,sha256=xbFbtFDia36XLgaNrX2IwvAX3IDC_Odpj5BGoJSgiIE,2389
|
218
238
|
tests/unit_tests/test_crosshair.py,sha256=3OMAJ2ZaISYXMOtkXf1rPdy94vCr8njeLi6uHblBL9Q,5045
|
239
|
+
tests/unit_tests/test_device_box.py,sha256=q9IVFpt1NF3TBF0Jhk-I-LRiuvvHG3FGUalw4jEYwVo,3431
|
219
240
|
tests/unit_tests/test_device_input_base.py,sha256=r1tI7BFAhpv7V7gf_n5gjusyrBFOfuCqIkdVg7YA7vY,2444
|
220
241
|
tests/unit_tests/test_device_input_widgets.py,sha256=Q40xNKGvJT2dvNttRH68WZi0au8PwpUgBi2EB4LXfC8,5841
|
221
242
|
tests/unit_tests/test_generate_cli_client.py,sha256=ng-eV5iF7Dhm-6YpxYo99CMY0KgqoaZBQNkMeKULDBU,3355
|
@@ -230,10 +251,11 @@ tests/unit_tests/test_rpc_widget_handler.py,sha256=ceQ3BPnBIFY2Hy-sDPw0wxxREVTTp
|
|
230
251
|
tests/unit_tests/test_scan_control.py,sha256=Wr6KcE8av4sEIOx5VgYbzVCem3Jgb4Kzx_oOuvwlmkE,13459
|
231
252
|
tests/unit_tests/test_scan_control_group_box.py,sha256=HNqjP10B_NonikspNwKz9upJU-t7xf6hwBerNhbC-uo,5563
|
232
253
|
tests/unit_tests/test_setting_dialog.py,sha256=QbHWwLa1VGFwYie-SN3rjS3ICo7A44S4AKN2qeNvIKY,3137
|
254
|
+
tests/unit_tests/test_spinner.py,sha256=4_wQs56vQb6Sr1aTXMdW6LKpce2uM0tWMO3LPtAhSwU,774
|
233
255
|
tests/unit_tests/test_stop_button.py,sha256=tpQanzBUyl7qLXjbMUQqm3U3vShbKKARcnLpgsu3P0E,789
|
234
256
|
tests/unit_tests/test_text_box_widget.py,sha256=cT0uEHt_6d-FwST0A_wE9sFW9E3F_nJbKhuBAeU4yHg,1862
|
235
257
|
tests/unit_tests/test_toggle.py,sha256=Amzgres7te0tTQIDR2WMKSx9Kce44TxMpIPR6HZygXQ,832
|
236
|
-
tests/unit_tests/test_vscode_widget.py,sha256=
|
258
|
+
tests/unit_tests/test_vscode_widget.py,sha256=G1G7nCQGXFUn0BnMECE7mHmAm0C6pYx1JpEi_XEhodY,2682
|
237
259
|
tests/unit_tests/test_waveform1d.py,sha256=inc-CyRA_3-PE99WnR6vDdfRE1vgp-ZoLVJ-Qbq0qFY,15967
|
238
260
|
tests/unit_tests/test_website_widget.py,sha256=fBADIJJBAHU4Ro7u95kdemFVNv196UOcuO9oLHuHt8A,761
|
239
261
|
tests/unit_tests/test_widget_io.py,sha256=FeL3ZYSBQnRt6jxj8VGYw1cmcicRQyHKleahw7XIyR0,3475
|
@@ -243,8 +265,8 @@ tests/unit_tests/test_configs/config_device_no_entry.yaml,sha256=hdvue9KLc_kfNzG
|
|
243
265
|
tests/unit_tests/test_configs/config_scan.yaml,sha256=vo484BbWOjA_e-h6bTjSV9k7QaQHrlAvx-z8wtY-P4E,1915
|
244
266
|
tests/unit_tests/test_msgs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
245
267
|
tests/unit_tests/test_msgs/available_scans_message.py,sha256=m_z97hIrjHXXMa2Ex-UvsPmTxOYXfjxyJaGkIY6StTY,46532
|
246
|
-
bec_widgets-0.
|
247
|
-
bec_widgets-0.
|
248
|
-
bec_widgets-0.
|
249
|
-
bec_widgets-0.
|
250
|
-
bec_widgets-0.
|
268
|
+
bec_widgets-0.83.0.dist-info/METADATA,sha256=xSeHtjGGoakyD7GAov5Syu1U4lMGeuIPyORPJeEfz9o,1309
|
269
|
+
bec_widgets-0.83.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
|
270
|
+
bec_widgets-0.83.0.dist-info/entry_points.txt,sha256=3otEkCdDB9LZJuBLzG4pFLK5Di0CVybN_12IsZrQ-58,166
|
271
|
+
bec_widgets-0.83.0.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
|
272
|
+
bec_widgets-0.83.0.dist-info/RECORD,,
|
pyproject.toml
CHANGED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
tests/unit_tests/client_mocks.py
CHANGED
@@ -49,11 +49,19 @@ class FakePositioner(FakeDevice):
|
|
49
49
|
self.read_value = read_value
|
50
50
|
self.name = name
|
51
51
|
|
52
|
+
@property
|
53
|
+
def precision(self):
|
54
|
+
return 3
|
55
|
+
|
52
56
|
def set_read_value(self, value):
|
53
57
|
self.read_value = value
|
54
58
|
|
55
59
|
def read(self):
|
56
|
-
return {
|
60
|
+
return {
|
61
|
+
self.name: {"value": self.read_value},
|
62
|
+
f"{self.name}_setpoint": {"value": self.read_value},
|
63
|
+
f"{self.name}_motor_is_moving": {"value": 0},
|
64
|
+
}
|
57
65
|
|
58
66
|
def set_limits(self, limits):
|
59
67
|
self.limits = limits
|
@@ -0,0 +1,98 @@
|
|
1
|
+
from unittest import mock
|
2
|
+
|
3
|
+
import pytest
|
4
|
+
from bec_lib.endpoints import MessageEndpoints
|
5
|
+
from bec_lib.messages import ScanQueueMessage
|
6
|
+
from qtpy.QtGui import QValidator
|
7
|
+
|
8
|
+
from bec_widgets.widgets.device_box.device_box import DeviceBox
|
9
|
+
|
10
|
+
from .client_mocks import mocked_client
|
11
|
+
|
12
|
+
|
13
|
+
@pytest.fixture
|
14
|
+
def device_box(qtbot, mocked_client):
|
15
|
+
with mock.patch("bec_widgets.widgets.device_box.device_box.uuid.uuid4") as mock_uuid:
|
16
|
+
mock_uuid.return_value = "fake_uuid"
|
17
|
+
db = DeviceBox(device="samx", client=mocked_client)
|
18
|
+
qtbot.addWidget(db)
|
19
|
+
yield db
|
20
|
+
|
21
|
+
|
22
|
+
def test_device_box(device_box):
|
23
|
+
assert device_box.device == "samx"
|
24
|
+
data = device_box.dev["samx"].read()
|
25
|
+
|
26
|
+
setpoint_text = device_box.ui.setpoint.text()
|
27
|
+
# check that the setpoint is taken correctly after init
|
28
|
+
assert float(setpoint_text) == data["samx_setpoint"]["value"]
|
29
|
+
|
30
|
+
# check that the precision is taken correctly after init
|
31
|
+
precision = device_box.dev["samx"].precision
|
32
|
+
assert setpoint_text == f"{data['samx_setpoint']['value']:.{precision}f}"
|
33
|
+
|
34
|
+
# check that the step size is set according to the device precision
|
35
|
+
assert device_box.ui.step_size.value() == 10**-precision * 10
|
36
|
+
|
37
|
+
|
38
|
+
def test_device_box_update_limits(device_box):
|
39
|
+
device_box._limits = None
|
40
|
+
device_box.update_limits([0, 10])
|
41
|
+
assert device_box._limits == [0, 10]
|
42
|
+
assert device_box.setpoint_validator.bottom() == 0
|
43
|
+
assert device_box.setpoint_validator.top() == 10
|
44
|
+
assert device_box.setpoint_validator.validate("100", 0) == (
|
45
|
+
QValidator.State.Intermediate,
|
46
|
+
"100",
|
47
|
+
0,
|
48
|
+
)
|
49
|
+
|
50
|
+
device_box.update_limits(None)
|
51
|
+
assert device_box._limits is None
|
52
|
+
assert device_box.setpoint_validator.validate("100", 0) == (
|
53
|
+
QValidator.State.Acceptable,
|
54
|
+
"100",
|
55
|
+
0,
|
56
|
+
)
|
57
|
+
|
58
|
+
|
59
|
+
def test_device_box_on_stop(device_box):
|
60
|
+
with mock.patch.object(device_box.client.connector, "send") as mock_send:
|
61
|
+
device_box.on_stop()
|
62
|
+
params = {"device": "samx", "rpc_id": "fake_uuid", "func": "stop", "args": [], "kwargs": {}}
|
63
|
+
msg = ScanQueueMessage(
|
64
|
+
scan_type="device_rpc",
|
65
|
+
parameter=params,
|
66
|
+
queue="emergency",
|
67
|
+
metadata={"RID": "fake_uuid", "response": False},
|
68
|
+
)
|
69
|
+
mock_send.assert_called_once_with(MessageEndpoints.scan_queue_request(), msg)
|
70
|
+
|
71
|
+
|
72
|
+
def test_device_box_setpoint_change(device_box):
|
73
|
+
with mock.patch.object(device_box.dev["samx"], "move") as mock_move:
|
74
|
+
device_box.ui.setpoint.setText("100")
|
75
|
+
device_box.on_setpoint_change()
|
76
|
+
mock_move.assert_called_once_with(100, relative=False)
|
77
|
+
|
78
|
+
|
79
|
+
def test_device_box_on_tweak_right(device_box):
|
80
|
+
with mock.patch.object(device_box.dev["samx"], "move") as mock_move:
|
81
|
+
device_box.ui.step_size.setValue(0.1)
|
82
|
+
device_box.on_tweak_right()
|
83
|
+
mock_move.assert_called_once_with(0.1, relative=True)
|
84
|
+
|
85
|
+
|
86
|
+
def test_device_box_on_tweak_left(device_box):
|
87
|
+
with mock.patch.object(device_box.dev["samx"], "move") as mock_move:
|
88
|
+
device_box.ui.step_size.setValue(0.1)
|
89
|
+
device_box.on_tweak_left()
|
90
|
+
mock_move.assert_called_once_with(-0.1, relative=True)
|
91
|
+
|
92
|
+
|
93
|
+
def test_device_box_setpoint_out_of_range(device_box):
|
94
|
+
device_box.update_limits([0, 10])
|
95
|
+
device_box.ui.setpoint.setText("100")
|
96
|
+
device_box.on_setpoint_change()
|
97
|
+
assert device_box.ui.setpoint.text() == "100"
|
98
|
+
assert device_box.ui.setpoint.hasAcceptableInput() == False
|