bec-widgets 0.81.0__py3-none-any.whl → 0.82.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- CHANGELOG.md +50 -46
- PKG-INFO +1 -1
- bec_widgets/cli/client.py +1 -0
- bec_widgets/examples/__init__.py +0 -9
- bec_widgets/qt_utils/settings_dialog.py +107 -0
- bec_widgets/{widgets/toolbar → qt_utils}/toolbar.py +1 -30
- bec_widgets/widgets/{device_inputs → base_classes}/device_input_base.py +2 -0
- bec_widgets/widgets/{buttons/color_button → color_button}/color_button_plugin.py +1 -1
- bec_widgets/widgets/{buttons/color_button → color_button}/register_color_button.py +1 -1
- bec_widgets/widgets/device_combobox/assets/device_combobox_icon.png +0 -0
- bec_widgets/widgets/{device_inputs/device_combobox → device_combobox}/device_combobox.py +2 -2
- bec_widgets/widgets/device_combobox/device_combobox.pyproject +3 -0
- bec_widgets/widgets/{device_inputs/device_combobox → device_combobox}/device_combobox_plugin.py +6 -3
- bec_widgets/widgets/{device_inputs/device_combobox → device_combobox}/register_device_combobox.py +1 -3
- bec_widgets/widgets/device_line_edit/assets/line_edit_icon.png +0 -0
- bec_widgets/widgets/{device_inputs/device_line_edit → device_line_edit}/device_line_edit.py +2 -2
- bec_widgets/widgets/device_line_edit/device_line_edit.pyproject +3 -0
- bec_widgets/widgets/{device_inputs/device_line_edit → device_line_edit}/device_line_edit_plugin.py +6 -3
- bec_widgets/widgets/{device_inputs/device_line_edit → device_line_edit}/register_device_line_edit.py +1 -3
- bec_widgets/widgets/figure/plots/motor_map/motor_map.py +10 -8
- bec_widgets/widgets/figure/plots/waveform/waveform.py +8 -2
- bec_widgets/widgets/motor_map/motor_map_dialog/motor_map_settings.py +5 -31
- bec_widgets/widgets/motor_map/motor_map_dialog/motor_map_toolbar.py +2 -2
- bec_widgets/widgets/motor_map/motor_map_widget.py +6 -15
- bec_widgets/widgets/scan_control/scan_control.py +1 -1
- bec_widgets/widgets/scan_control/scan_group_box.py +1 -1
- bec_widgets/widgets/stop_button/assets/stop.png +0 -0
- bec_widgets/widgets/stop_button/register_stop_button.py +15 -0
- bec_widgets/widgets/{buttons/stop_button → stop_button}/stop_button.py +5 -12
- bec_widgets/widgets/stop_button/stop_button.pyproject +1 -0
- bec_widgets/widgets/stop_button/stop_button_plugin.py +57 -0
- bec_widgets/widgets/toggle/register_toggle_switch.py +15 -0
- bec_widgets/widgets/toggle/toggle.py +149 -0
- bec_widgets/widgets/toggle/toggle_switch.pyproject +1 -0
- bec_widgets/widgets/toggle/toggle_switch_plugin.py +54 -0
- {bec_widgets-0.81.0.dist-info → bec_widgets-0.82.1.dist-info}/METADATA +1 -1
- {bec_widgets-0.81.0.dist-info → bec_widgets-0.82.1.dist-info}/RECORD +58 -64
- pyproject.toml +1 -1
- tests/unit_tests/client_mocks.py +8 -0
- tests/unit_tests/test_device_input_base.py +2 -2
- tests/unit_tests/test_device_input_widgets.py +4 -2
- tests/unit_tests/test_motor_map_widget.py +196 -0
- tests/unit_tests/test_setting_dialog.py +97 -0
- tests/unit_tests/test_stop_button.py +5 -2
- tests/unit_tests/test_toggle.py +38 -0
- bec_widgets/examples/motor_movement/__init__.py +0 -9
- bec_widgets/examples/motor_movement/motor_control_compilations.py +0 -250
- bec_widgets/examples/motor_movement/motor_controller.ui +0 -926
- bec_widgets/widgets/buttons/__init__.py +0 -1
- bec_widgets/widgets/device_inputs/__init__.py +0 -2
- bec_widgets/widgets/device_inputs/device_combobox/device_combobox.pyproject +0 -4
- bec_widgets/widgets/device_inputs/device_combobox/launch_device_combobox.py +0 -11
- bec_widgets/widgets/device_inputs/device_line_edit/device_line_edit.pyproject +0 -4
- bec_widgets/widgets/device_inputs/device_line_edit/launch_device_line_edit.py +0 -11
- bec_widgets/widgets/motor_control/motor_control.py +0 -252
- bec_widgets/widgets/motor_control/motor_table/motor_table.py +0 -484
- bec_widgets/widgets/motor_control/motor_table/motor_table.ui +0 -113
- bec_widgets/widgets/motor_control/movement_absolute/movement_absolute.py +0 -159
- bec_widgets/widgets/motor_control/movement_absolute/movement_absolute.ui +0 -149
- bec_widgets/widgets/motor_control/movement_relative/__init__.py +0 -0
- bec_widgets/widgets/motor_control/movement_relative/movement_relative.py +0 -230
- bec_widgets/widgets/motor_control/movement_relative/movement_relative.ui +0 -298
- bec_widgets/widgets/motor_control/selection/__init__.py +0 -0
- bec_widgets/widgets/motor_control/selection/selection.py +0 -110
- bec_widgets/widgets/motor_control/selection/selection.ui +0 -69
- bec_widgets/widgets/toolbar/__init__.py +0 -1
- tests/unit_tests/test_motor_control.py +0 -588
- /bec_widgets/{widgets/buttons/color_button → qt_utils}/__init__.py +0 -0
- /bec_widgets/widgets/{buttons/stop_button → base_classes}/__init__.py +0 -0
- /bec_widgets/widgets/{device_inputs/device_combobox → color_button}/__init__.py +0 -0
- /bec_widgets/widgets/{buttons/color_button → color_button}/assets/color_button.png +0 -0
- /bec_widgets/widgets/{buttons/color_button → color_button}/color_button.py +0 -0
- /bec_widgets/widgets/{buttons/color_button → color_button}/color_button.pyproject +0 -0
- /bec_widgets/widgets/{device_inputs/device_line_edit → device_combobox}/__init__.py +0 -0
- /bec_widgets/widgets/{motor_control → device_line_edit}/__init__.py +0 -0
- /bec_widgets/widgets/{motor_control/motor_table → stop_button}/__init__.py +0 -0
- /bec_widgets/widgets/{motor_control/movement_absolute → toggle}/__init__.py +0 -0
- {bec_widgets-0.81.0.dist-info → bec_widgets-0.82.1.dist-info}/WHEEL +0 -0
- {bec_widgets-0.81.0.dist-info → bec_widgets-0.82.1.dist-info}/entry_points.txt +0 -0
- {bec_widgets-0.81.0.dist-info → bec_widgets-0.82.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,7 +1,7 @@
|
|
1
1
|
import pytest
|
2
2
|
|
3
|
-
from bec_widgets.widgets.
|
4
|
-
from bec_widgets.widgets.
|
3
|
+
from bec_widgets.widgets.device_combobox.device_combobox import DeviceComboBox
|
4
|
+
from bec_widgets.widgets.device_line_edit.device_line_edit import DeviceLineEdit
|
5
5
|
|
6
6
|
from .client_mocks import mocked_client
|
7
7
|
|
@@ -67,6 +67,7 @@ def test_device_input_combobox_init(device_input_combobox):
|
|
67
67
|
"bpm3a",
|
68
68
|
"bpm3i",
|
69
69
|
"eiger",
|
70
|
+
"test",
|
70
71
|
]
|
71
72
|
|
72
73
|
|
@@ -153,6 +154,7 @@ def test_device_input_line_edit_init(device_input_line_edit):
|
|
153
154
|
"bpm3a",
|
154
155
|
"bpm3i",
|
155
156
|
"eiger",
|
157
|
+
"test",
|
156
158
|
]
|
157
159
|
|
158
160
|
|
@@ -0,0 +1,196 @@
|
|
1
|
+
from unittest.mock import MagicMock, patch
|
2
|
+
|
3
|
+
import pytest
|
4
|
+
|
5
|
+
from bec_widgets.widgets.motor_map.motor_map_dialog.motor_map_settings import MotorMapSettings
|
6
|
+
from bec_widgets.widgets.motor_map.motor_map_widget import BECMotorMapWidget
|
7
|
+
|
8
|
+
from .client_mocks import mocked_client
|
9
|
+
|
10
|
+
|
11
|
+
@pytest.fixture
|
12
|
+
def motor_map_widget(qtbot, mocked_client):
|
13
|
+
widget = BECMotorMapWidget(client=mocked_client())
|
14
|
+
widget.toolbar.widgets["motor_x"].device_combobox.set_device_filter("FakePositioner")
|
15
|
+
widget.toolbar.widgets["motor_y"].device_combobox.set_device_filter("FakePositioner")
|
16
|
+
qtbot.addWidget(widget)
|
17
|
+
qtbot.waitExposed(widget)
|
18
|
+
yield widget
|
19
|
+
widget.close()
|
20
|
+
|
21
|
+
|
22
|
+
@pytest.fixture
|
23
|
+
def mock_motor_map(motor_map_widget):
|
24
|
+
motor_map_mock = MagicMock()
|
25
|
+
motor_map_widget.map = motor_map_mock
|
26
|
+
return motor_map_mock
|
27
|
+
|
28
|
+
|
29
|
+
def test_motor_map_widget_init(motor_map_widget):
|
30
|
+
assert motor_map_widget is not None
|
31
|
+
assert motor_map_widget.client is not None
|
32
|
+
assert isinstance(motor_map_widget, BECMotorMapWidget)
|
33
|
+
assert motor_map_widget.config.widget_class == "BECMotorMapWidget"
|
34
|
+
|
35
|
+
# check initial state of toolbar actions
|
36
|
+
assert motor_map_widget.toolbar.widgets["connect"].action.isEnabled() == True
|
37
|
+
assert motor_map_widget.toolbar.widgets["config"].action.isEnabled() == False
|
38
|
+
assert motor_map_widget.toolbar.widgets["history"].action.isEnabled() == False
|
39
|
+
assert (
|
40
|
+
motor_map_widget.toolbar.widgets["motor_x"].device_combobox.config.device_filter
|
41
|
+
== "FakePositioner"
|
42
|
+
)
|
43
|
+
assert (
|
44
|
+
motor_map_widget.toolbar.widgets["motor_y"].device_combobox.config.device_filter
|
45
|
+
== "FakePositioner"
|
46
|
+
)
|
47
|
+
assert motor_map_widget.map.motor_x is None
|
48
|
+
assert motor_map_widget.map.motor_y is None
|
49
|
+
|
50
|
+
|
51
|
+
###################################
|
52
|
+
# Toolbar Actions
|
53
|
+
###################################
|
54
|
+
|
55
|
+
|
56
|
+
def test_motor_map_widget_change_motors_enable_toolbar(motor_map_widget):
|
57
|
+
motor_map_widget.change_motors("samx", "samy")
|
58
|
+
assert motor_map_widget.map.motor_x == "samx"
|
59
|
+
assert motor_map_widget.map.motor_y == "samy"
|
60
|
+
assert motor_map_widget.toolbar.widgets["motor_x"].device_combobox.currentText() == "samx"
|
61
|
+
assert motor_map_widget.toolbar.widgets["motor_y"].device_combobox.currentText() == "samy"
|
62
|
+
assert motor_map_widget.toolbar.widgets["config"].action.isEnabled() == True
|
63
|
+
assert motor_map_widget.toolbar.widgets["history"].action.isEnabled() == True
|
64
|
+
|
65
|
+
|
66
|
+
###################################
|
67
|
+
# Wrapper methods for MotorMap
|
68
|
+
###################################
|
69
|
+
|
70
|
+
|
71
|
+
def test_change_motors(motor_map_widget, mock_motor_map):
|
72
|
+
motor_map_widget.change_motors("motor_x", "motor_y", "motor_x_entry", "motor_y_entry", True)
|
73
|
+
mock_motor_map.change_motors.assert_called_once_with(
|
74
|
+
"motor_x", "motor_y", "motor_x_entry", "motor_y_entry", True
|
75
|
+
)
|
76
|
+
|
77
|
+
|
78
|
+
def test_get_data(motor_map_widget, mock_motor_map):
|
79
|
+
motor_map_widget.get_data()
|
80
|
+
mock_motor_map.get_data.assert_called_once()
|
81
|
+
|
82
|
+
|
83
|
+
def test_reset_history(motor_map_widget, mock_motor_map):
|
84
|
+
motor_map_widget.reset_history()
|
85
|
+
mock_motor_map.reset_history.assert_called_once()
|
86
|
+
|
87
|
+
|
88
|
+
def test_set_color(motor_map_widget, mock_motor_map):
|
89
|
+
motor_map_widget.set_color("blue")
|
90
|
+
mock_motor_map.set_color.assert_called_once_with("blue")
|
91
|
+
|
92
|
+
|
93
|
+
def test_set_max_points(motor_map_widget, mock_motor_map):
|
94
|
+
motor_map_widget.set_max_points(100)
|
95
|
+
mock_motor_map.set_max_points.assert_called_once_with(100)
|
96
|
+
|
97
|
+
|
98
|
+
def test_set_precision(motor_map_widget, mock_motor_map):
|
99
|
+
motor_map_widget.set_precision(2)
|
100
|
+
mock_motor_map.set_precision.assert_called_once_with(2)
|
101
|
+
|
102
|
+
|
103
|
+
def test_set_num_dim_points(motor_map_widget, mock_motor_map):
|
104
|
+
motor_map_widget.set_num_dim_points(50)
|
105
|
+
mock_motor_map.set_num_dim_points.assert_called_once_with(50)
|
106
|
+
|
107
|
+
|
108
|
+
def test_set_background_value(motor_map_widget, mock_motor_map):
|
109
|
+
motor_map_widget.set_background_value(128)
|
110
|
+
mock_motor_map.set_background_value.assert_called_once_with(128)
|
111
|
+
|
112
|
+
|
113
|
+
def test_set_scatter_size(motor_map_widget, mock_motor_map):
|
114
|
+
motor_map_widget.set_scatter_size(10)
|
115
|
+
mock_motor_map.set_scatter_size.assert_called_once_with(10)
|
116
|
+
|
117
|
+
|
118
|
+
###################################
|
119
|
+
# MotorMap Dialog
|
120
|
+
###################################
|
121
|
+
|
122
|
+
|
123
|
+
def test_motor_map_widget_clicked(motor_map_widget, qtbot):
|
124
|
+
motor_map_widget.toolbar.widgets["motor_x"].device_combobox.setCurrentText("samx")
|
125
|
+
motor_map_widget.toolbar.widgets["motor_y"].device_combobox.setCurrentText("samy")
|
126
|
+
motor_map_widget.toolbar.widgets["connect"].action.trigger()
|
127
|
+
|
128
|
+
qtbot.wait(200)
|
129
|
+
|
130
|
+
assert motor_map_widget.map.motor_x == "samx"
|
131
|
+
assert motor_map_widget.map.motor_y == "samy"
|
132
|
+
assert motor_map_widget.toolbar.widgets["config"].action.isEnabled() == True
|
133
|
+
assert motor_map_widget.toolbar.widgets["history"].action.isEnabled() == True
|
134
|
+
|
135
|
+
|
136
|
+
@pytest.fixture
|
137
|
+
def motor_map_settings(qtbot):
|
138
|
+
widget = MotorMapSettings()
|
139
|
+
qtbot.addWidget(widget)
|
140
|
+
qtbot.waitExposed(widget)
|
141
|
+
yield widget
|
142
|
+
widget.close()
|
143
|
+
|
144
|
+
|
145
|
+
def test_display_current_settings(motor_map_settings):
|
146
|
+
config = {
|
147
|
+
"max_points": 100,
|
148
|
+
"num_dim_points": 50,
|
149
|
+
"precision": 2,
|
150
|
+
"scatter_size": 10,
|
151
|
+
"background_value": 128,
|
152
|
+
"color": (255, 0, 0, 255),
|
153
|
+
}
|
154
|
+
|
155
|
+
with patch("bec_widgets.utils.widget_io.WidgetIO.set_value") as mock_set_value:
|
156
|
+
with patch.object(motor_map_settings.ui.color, "setColor") as mock_set_color:
|
157
|
+
motor_map_settings.display_current_settings(config)
|
158
|
+
mock_set_value.assert_any_call(motor_map_settings.ui.max_points, config["max_points"])
|
159
|
+
mock_set_value.assert_any_call(
|
160
|
+
motor_map_settings.ui.trace_dim, config["num_dim_points"]
|
161
|
+
)
|
162
|
+
mock_set_value.assert_any_call(motor_map_settings.ui.precision, config["precision"])
|
163
|
+
mock_set_value.assert_any_call(
|
164
|
+
motor_map_settings.ui.scatter_size, config["scatter_size"]
|
165
|
+
)
|
166
|
+
mock_set_value.assert_any_call(
|
167
|
+
motor_map_settings.ui.background_value, 50
|
168
|
+
) # 128/255*100 = 50
|
169
|
+
mock_set_color.assert_called_once_with(config["color"])
|
170
|
+
|
171
|
+
|
172
|
+
def test_accept_changes(motor_map_settings):
|
173
|
+
with patch(
|
174
|
+
"bec_widgets.utils.widget_io.WidgetIO.get_value", side_effect=[100, 50, 2, 10, 50]
|
175
|
+
) as mock_get_value:
|
176
|
+
with patch.object(
|
177
|
+
motor_map_settings.ui.color, "get_color", return_value=(255, 0, 0, 255)
|
178
|
+
) as mock_get_color:
|
179
|
+
mock_target_widget = MagicMock()
|
180
|
+
motor_map_settings.set_target_widget(mock_target_widget)
|
181
|
+
|
182
|
+
motor_map_settings.accept_changes()
|
183
|
+
|
184
|
+
mock_get_value.assert_any_call(motor_map_settings.ui.max_points)
|
185
|
+
mock_get_value.assert_any_call(motor_map_settings.ui.trace_dim)
|
186
|
+
mock_get_value.assert_any_call(motor_map_settings.ui.precision)
|
187
|
+
mock_get_value.assert_any_call(motor_map_settings.ui.scatter_size)
|
188
|
+
mock_get_value.assert_any_call(motor_map_settings.ui.background_value)
|
189
|
+
mock_get_color.assert_called_once()
|
190
|
+
|
191
|
+
mock_target_widget.set_max_points.assert_called_once_with(100)
|
192
|
+
mock_target_widget.set_num_dim_points.assert_called_once_with(50)
|
193
|
+
mock_target_widget.set_precision.assert_called_once_with(2)
|
194
|
+
mock_target_widget.set_scatter_size.assert_called_once_with(10)
|
195
|
+
mock_target_widget.set_background_value.assert_called_once_with(127)
|
196
|
+
mock_target_widget.set_color.assert_called_once_with((255, 0, 0, 255))
|
@@ -0,0 +1,97 @@
|
|
1
|
+
from unittest.mock import MagicMock, patch
|
2
|
+
|
3
|
+
import pytest
|
4
|
+
from qtpy.QtWidgets import QWidget
|
5
|
+
|
6
|
+
from bec_widgets.qt_utils.settings_dialog import SettingsDialog, SettingWidget
|
7
|
+
|
8
|
+
###################################
|
9
|
+
# SettingWidget base class tests
|
10
|
+
###################################
|
11
|
+
|
12
|
+
|
13
|
+
@pytest.fixture
|
14
|
+
def setting_widget(qtbot):
|
15
|
+
widget = SettingWidget()
|
16
|
+
qtbot.addWidget(widget)
|
17
|
+
qtbot.waitExposed(widget)
|
18
|
+
yield widget
|
19
|
+
widget.close()
|
20
|
+
|
21
|
+
|
22
|
+
def test_setting_widget_initialization(setting_widget):
|
23
|
+
assert setting_widget.target_widget is None
|
24
|
+
|
25
|
+
|
26
|
+
def test_setting_widget_set_target_widget(setting_widget):
|
27
|
+
mock_target = MagicMock(spec=QWidget)
|
28
|
+
setting_widget.set_target_widget(mock_target)
|
29
|
+
assert setting_widget.target_widget == mock_target
|
30
|
+
|
31
|
+
|
32
|
+
def test_setting_widget_accept_changes(setting_widget):
|
33
|
+
with patch.object(setting_widget, "accept_changes") as mock_accept_changes:
|
34
|
+
setting_widget.accept_changes()
|
35
|
+
mock_accept_changes.assert_called_once()
|
36
|
+
|
37
|
+
|
38
|
+
def test_setting_widget_display_current_settings(setting_widget):
|
39
|
+
config_dict = {"setting1": "value1", "setting2": "value2"}
|
40
|
+
with patch.object(setting_widget, "display_current_settings") as mock_display_current_settings:
|
41
|
+
setting_widget.display_current_settings(config_dict)
|
42
|
+
mock_display_current_settings.assert_called_once_with(config_dict)
|
43
|
+
|
44
|
+
|
45
|
+
###################################
|
46
|
+
# SettingsDialog tests
|
47
|
+
###################################
|
48
|
+
@pytest.fixture
|
49
|
+
def settings_dialog(qtbot):
|
50
|
+
parent_widget = QWidget()
|
51
|
+
settings_widget = SettingWidget()
|
52
|
+
settings_widget.set_target_widget = MagicMock()
|
53
|
+
settings_widget.display_current_settings = MagicMock()
|
54
|
+
settings_widget.accept_changes = MagicMock()
|
55
|
+
|
56
|
+
dialog = SettingsDialog(
|
57
|
+
parent=parent_widget,
|
58
|
+
settings_widget=settings_widget,
|
59
|
+
window_title="Test Settings",
|
60
|
+
config={"setting1": "value1", "setting2": "value2"},
|
61
|
+
)
|
62
|
+
qtbot.addWidget(dialog)
|
63
|
+
qtbot.waitExposed(dialog)
|
64
|
+
yield dialog, parent_widget, settings_widget
|
65
|
+
dialog.close()
|
66
|
+
|
67
|
+
|
68
|
+
def test_settings_dialog_initialization(settings_dialog):
|
69
|
+
dialog, parent_widget, settings_widget = settings_dialog
|
70
|
+
|
71
|
+
assert dialog.windowTitle() == "Test Settings"
|
72
|
+
settings_widget.set_target_widget.assert_called_once_with(parent_widget)
|
73
|
+
settings_widget.display_current_settings.assert_called_once_with(
|
74
|
+
{"setting1": "value1", "setting2": "value2"}
|
75
|
+
)
|
76
|
+
|
77
|
+
|
78
|
+
def test_settings_dialog_accept(settings_dialog, qtbot):
|
79
|
+
dialog, _, settings_widget = settings_dialog
|
80
|
+
|
81
|
+
dialog.button_box.buttons()[0].click() # OK Button
|
82
|
+
settings_widget.accept_changes.assert_called_once()
|
83
|
+
|
84
|
+
|
85
|
+
def test_settings_dialog_reject(settings_dialog, qtbot):
|
86
|
+
dialog, _, _ = settings_dialog
|
87
|
+
|
88
|
+
with patch.object(dialog, "reject", wraps=dialog.reject) as mock_reject:
|
89
|
+
dialog.button_box.buttons()[1].click() # Cancel Button
|
90
|
+
mock_reject.assert_called_once()
|
91
|
+
|
92
|
+
|
93
|
+
def test_settings_dialog_apply_changes(settings_dialog, qtbot):
|
94
|
+
dialog, _, settings_widget = settings_dialog
|
95
|
+
|
96
|
+
dialog.apply_button.click()
|
97
|
+
settings_widget.accept_changes.assert_called_once()
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
import pytest
|
4
4
|
|
5
|
-
from bec_widgets.widgets.
|
5
|
+
from bec_widgets.widgets.stop_button.stop_button import StopButton
|
6
6
|
|
7
7
|
from .client_mocks import mocked_client
|
8
8
|
|
@@ -18,7 +18,10 @@ def stop_button(qtbot, mocked_client):
|
|
18
18
|
|
19
19
|
def test_stop_button(stop_button):
|
20
20
|
assert stop_button.text() == "Stop"
|
21
|
-
assert
|
21
|
+
assert (
|
22
|
+
stop_button.styleSheet()
|
23
|
+
== "background-color: #cc181e; color: white; font-weight: bold; font-size: 12px;"
|
24
|
+
)
|
22
25
|
stop_button.click()
|
23
26
|
assert stop_button.queue.request_scan_abortion.called
|
24
27
|
assert stop_button.queue.request_queue_reset.called
|
@@ -0,0 +1,38 @@
|
|
1
|
+
import pytest
|
2
|
+
from qtpy.QtCore import QPointF, Qt
|
3
|
+
|
4
|
+
from bec_widgets.widgets.toggle.toggle import ToggleSwitch
|
5
|
+
|
6
|
+
|
7
|
+
@pytest.fixture
|
8
|
+
def toggle(qtbot):
|
9
|
+
widget = ToggleSwitch()
|
10
|
+
qtbot.addWidget(widget)
|
11
|
+
qtbot.waitExposed(widget)
|
12
|
+
yield widget
|
13
|
+
|
14
|
+
|
15
|
+
def test_toggle(toggle):
|
16
|
+
toggle.checked = False
|
17
|
+
assert toggle.checked is False
|
18
|
+
|
19
|
+
assert toggle.thumb_pos == QPointF(3, 2)
|
20
|
+
|
21
|
+
toggle.checked = True
|
22
|
+
assert toggle.checked is True
|
23
|
+
|
24
|
+
assert toggle.thumb_pos == QPointF(22, 2)
|
25
|
+
|
26
|
+
|
27
|
+
def test_toggle_click(qtbot, toggle):
|
28
|
+
init_state = toggle.checked
|
29
|
+
|
30
|
+
qtbot.mouseClick(toggle, Qt.LeftButton)
|
31
|
+
toggle.paintEvent(None)
|
32
|
+
assert toggle.checked is not init_state
|
33
|
+
|
34
|
+
init_state = toggle.checked
|
35
|
+
|
36
|
+
qtbot.mouseClick(toggle, Qt.LeftButton)
|
37
|
+
toggle.paintEvent(None)
|
38
|
+
assert toggle.checked is not init_state
|
@@ -1,250 +0,0 @@
|
|
1
|
-
# pylint: disable = no-name-in-module,missing-class-docstring, missing-module-docstring
|
2
|
-
|
3
|
-
import qdarktheme
|
4
|
-
from qtpy.QtCore import Qt
|
5
|
-
from qtpy.QtWidgets import QApplication, QSplitter, QVBoxLayout, QWidget
|
6
|
-
|
7
|
-
from bec_widgets.utils.bec_dispatcher import BECDispatcher
|
8
|
-
from bec_widgets.widgets.motor_control.motor_control import MotorThread
|
9
|
-
from bec_widgets.widgets.motor_control.motor_table.motor_table import MotorCoordinateTable
|
10
|
-
from bec_widgets.widgets.motor_control.movement_absolute.movement_absolute import (
|
11
|
-
MotorControlAbsolute,
|
12
|
-
)
|
13
|
-
from bec_widgets.widgets.motor_control.movement_relative.movement_relative import (
|
14
|
-
MotorControlRelative,
|
15
|
-
)
|
16
|
-
from bec_widgets.widgets.motor_control.selection.selection import MotorControlSelection
|
17
|
-
|
18
|
-
CONFIG_DEFAULT = {
|
19
|
-
"motor_control": {
|
20
|
-
"motor_x": "samx",
|
21
|
-
"motor_y": "samy",
|
22
|
-
"step_size_x": 3,
|
23
|
-
"step_size_y": 3,
|
24
|
-
"precision": 4,
|
25
|
-
"step_x_y_same": False,
|
26
|
-
"move_with_arrows": False,
|
27
|
-
},
|
28
|
-
"plot_settings": {
|
29
|
-
"colormap": "Greys",
|
30
|
-
"scatter_size": 5,
|
31
|
-
"max_points": 1000,
|
32
|
-
"num_dim_points": 100,
|
33
|
-
"precision": 2,
|
34
|
-
"num_columns": 1,
|
35
|
-
"background_value": 25,
|
36
|
-
},
|
37
|
-
"motors": [
|
38
|
-
{
|
39
|
-
"plot_name": "Motor Map",
|
40
|
-
"x_label": "Motor X",
|
41
|
-
"y_label": "Motor Y",
|
42
|
-
"signals": {
|
43
|
-
"x": [{"name": "samx", "entry": "samx"}],
|
44
|
-
"y": [{"name": "samy", "entry": "samy"}],
|
45
|
-
},
|
46
|
-
}
|
47
|
-
],
|
48
|
-
}
|
49
|
-
|
50
|
-
|
51
|
-
class MotorControlApp(QWidget):
|
52
|
-
def __init__(self, parent=None, client=None, config=None):
|
53
|
-
super().__init__(parent)
|
54
|
-
|
55
|
-
bec_dispatcher = BECDispatcher()
|
56
|
-
self.client = bec_dispatcher.client if client is None else client
|
57
|
-
self.config = config
|
58
|
-
|
59
|
-
# Widgets
|
60
|
-
self.motor_control_panel = MotorControlPanel(client=self.client, config=self.config)
|
61
|
-
# Create MotorMap
|
62
|
-
# self.motion_map = MotorMap(client=self.client, config=self.config)
|
63
|
-
# Create MotorCoordinateTable
|
64
|
-
self.motor_table = MotorCoordinateTable(client=self.client, config=self.config)
|
65
|
-
|
66
|
-
# Create the splitter and add MotorMap and MotorControlPanel
|
67
|
-
splitter = QSplitter(Qt.Horizontal)
|
68
|
-
# splitter.addWidget(self.motion_map)
|
69
|
-
splitter.addWidget(self.motor_control_panel)
|
70
|
-
splitter.addWidget(self.motor_table)
|
71
|
-
|
72
|
-
# Set the main layout
|
73
|
-
layout = QVBoxLayout(self)
|
74
|
-
layout.addWidget(splitter)
|
75
|
-
self.setLayout(layout)
|
76
|
-
|
77
|
-
# Connecting signals and slots
|
78
|
-
# self.motor_control_panel.selection_widget.selected_motors_signal.connect(
|
79
|
-
# lambda x, y: self.motion_map.change_motors(x, y, 0)
|
80
|
-
# )
|
81
|
-
self.motor_control_panel.absolute_widget.coordinates_signal.connect(
|
82
|
-
self.motor_table.add_coordinate
|
83
|
-
)
|
84
|
-
self.motor_control_panel.relative_widget.precision_signal.connect(
|
85
|
-
self.motor_table.set_precision
|
86
|
-
)
|
87
|
-
self.motor_control_panel.relative_widget.precision_signal.connect(
|
88
|
-
self.motor_control_panel.absolute_widget.set_precision
|
89
|
-
)
|
90
|
-
|
91
|
-
# self.motor_table.plot_coordinates_signal.connect(self.motion_map.plot_saved_coordinates)
|
92
|
-
|
93
|
-
|
94
|
-
class MotorControlMap(QWidget):
|
95
|
-
def __init__(self, parent=None, client=None, config=None):
|
96
|
-
super().__init__(parent)
|
97
|
-
|
98
|
-
bec_dispatcher = BECDispatcher()
|
99
|
-
self.client = bec_dispatcher.client if client is None else client
|
100
|
-
self.config = config
|
101
|
-
|
102
|
-
# Widgets
|
103
|
-
self.motor_control_panel = MotorControlPanel(client=self.client, config=self.config)
|
104
|
-
# Create MotorMap
|
105
|
-
# self.motion_map = MotorMap(client=self.client, config=self.config)
|
106
|
-
|
107
|
-
# Create the splitter and add MotorMap and MotorControlPanel
|
108
|
-
splitter = QSplitter(Qt.Horizontal)
|
109
|
-
# splitter.addWidget(self.motion_map)
|
110
|
-
splitter.addWidget(self.motor_control_panel)
|
111
|
-
|
112
|
-
# Set the main layout
|
113
|
-
layout = QVBoxLayout(self)
|
114
|
-
layout.addWidget(splitter)
|
115
|
-
self.setLayout(layout)
|
116
|
-
|
117
|
-
# Connecting signals and slots
|
118
|
-
# self.motor_control_panel.selection_widget.selected_motors_signal.connect(
|
119
|
-
# lambda x, y: self.motion_map.change_motors(x, y, 0)
|
120
|
-
# )
|
121
|
-
|
122
|
-
|
123
|
-
class MotorControlPanel(QWidget):
|
124
|
-
def __init__(self, parent=None, client=None, config=None):
|
125
|
-
super().__init__(parent)
|
126
|
-
|
127
|
-
bec_dispatcher = BECDispatcher()
|
128
|
-
self.client = bec_dispatcher.client if client is None else client
|
129
|
-
self.config = config
|
130
|
-
|
131
|
-
self.motor_thread = MotorThread(client=self.client)
|
132
|
-
|
133
|
-
self.selection_widget = MotorControlSelection(
|
134
|
-
client=self.client, config=self.config, motor_thread=self.motor_thread
|
135
|
-
)
|
136
|
-
self.relative_widget = MotorControlRelative(
|
137
|
-
client=self.client, config=self.config, motor_thread=self.motor_thread
|
138
|
-
)
|
139
|
-
self.absolute_widget = MotorControlAbsolute(
|
140
|
-
client=self.client, config=self.config, motor_thread=self.motor_thread
|
141
|
-
)
|
142
|
-
|
143
|
-
layout = QVBoxLayout(self)
|
144
|
-
|
145
|
-
layout.addWidget(self.selection_widget)
|
146
|
-
layout.addWidget(self.relative_widget)
|
147
|
-
layout.addWidget(self.absolute_widget)
|
148
|
-
|
149
|
-
# Connecting signals and slots
|
150
|
-
self.selection_widget.selected_motors_signal.connect(self.relative_widget.change_motors)
|
151
|
-
self.selection_widget.selected_motors_signal.connect(self.absolute_widget.change_motors)
|
152
|
-
|
153
|
-
# Set the window to a fixed size based on its contents
|
154
|
-
# self.layout().setSizeConstraint(layout.SetFixedSize)
|
155
|
-
|
156
|
-
|
157
|
-
class MotorControlPanelAbsolute(QWidget):
|
158
|
-
def __init__(self, parent=None, client=None, config=None):
|
159
|
-
super().__init__(parent)
|
160
|
-
|
161
|
-
bec_dispatcher = BECDispatcher()
|
162
|
-
self.client = bec_dispatcher.client if client is None else client
|
163
|
-
self.config = config
|
164
|
-
|
165
|
-
self.motor_thread = MotorThread(client=self.client)
|
166
|
-
|
167
|
-
self.selection_widget = MotorControlSelection(
|
168
|
-
client=client, config=config, motor_thread=self.motor_thread
|
169
|
-
)
|
170
|
-
self.absolute_widget = MotorControlAbsolute(
|
171
|
-
client=client, config=config, motor_thread=self.motor_thread
|
172
|
-
)
|
173
|
-
|
174
|
-
layout = QVBoxLayout(self)
|
175
|
-
layout.addWidget(self.selection_widget)
|
176
|
-
layout.addWidget(self.absolute_widget)
|
177
|
-
|
178
|
-
# Connecting signals and slots
|
179
|
-
self.selection_widget.selected_motors_signal.connect(self.absolute_widget.change_motors)
|
180
|
-
|
181
|
-
|
182
|
-
class MotorControlPanelRelative(QWidget):
|
183
|
-
def __init__(self, parent=None, client=None, config=None):
|
184
|
-
super().__init__(parent)
|
185
|
-
|
186
|
-
bec_dispatcher = BECDispatcher()
|
187
|
-
self.client = bec_dispatcher.client if client is None else client
|
188
|
-
self.config = config
|
189
|
-
|
190
|
-
self.motor_thread = MotorThread(client=self.client)
|
191
|
-
|
192
|
-
self.selection_widget = MotorControlSelection(
|
193
|
-
client=client, config=config, motor_thread=self.motor_thread
|
194
|
-
)
|
195
|
-
self.relative_widget = MotorControlRelative(
|
196
|
-
client=client, config=config, motor_thread=self.motor_thread
|
197
|
-
)
|
198
|
-
|
199
|
-
layout = QVBoxLayout(self)
|
200
|
-
layout.addWidget(self.selection_widget)
|
201
|
-
layout.addWidget(self.relative_widget)
|
202
|
-
|
203
|
-
# Connecting signals and slots
|
204
|
-
self.selection_widget.selected_motors_signal.connect(self.relative_widget.change_motors)
|
205
|
-
|
206
|
-
|
207
|
-
if __name__ == "__main__": # pragma: no cover
|
208
|
-
import argparse
|
209
|
-
import sys
|
210
|
-
|
211
|
-
parser = argparse.ArgumentParser(description="Run various Motor Control Widgets compositions.")
|
212
|
-
parser.add_argument(
|
213
|
-
"-v",
|
214
|
-
"--variant",
|
215
|
-
type=str,
|
216
|
-
choices=["app", "map", "panel", "panel_abs", "panel_rel"],
|
217
|
-
help="Select the variant of the motor control to run. "
|
218
|
-
"'app' for the full application, "
|
219
|
-
"'map' for MotorMap, "
|
220
|
-
"'panel' for the MotorControlPanel, "
|
221
|
-
"'panel_abs' for MotorControlPanel with absolute control, "
|
222
|
-
"'panel_rel' for MotorControlPanel with relative control.",
|
223
|
-
)
|
224
|
-
|
225
|
-
args = parser.parse_args()
|
226
|
-
|
227
|
-
bec_dispatcher = BECDispatcher()
|
228
|
-
client = bec_dispatcher.client
|
229
|
-
client.start()
|
230
|
-
|
231
|
-
app = QApplication([])
|
232
|
-
qdarktheme.setup_theme("auto")
|
233
|
-
|
234
|
-
if args.variant == "app":
|
235
|
-
window = MotorControlApp(client=client) # , config=CONFIG_DEFAULT)
|
236
|
-
elif args.variant == "map":
|
237
|
-
window = MotorControlMap(client=client) # , config=CONFIG_DEFAULT)
|
238
|
-
elif args.variant == "panel":
|
239
|
-
window = MotorControlPanel(client=client) # , config=CONFIG_DEFAULT)
|
240
|
-
elif args.variant == "panel_abs":
|
241
|
-
window = MotorControlPanelAbsolute(client=client) # , config=CONFIG_DEFAULT)
|
242
|
-
elif args.variant == "panel_rel":
|
243
|
-
window = MotorControlPanelRelative(client=client) # , config=CONFIG_DEFAULT)
|
244
|
-
else:
|
245
|
-
print("Please specify a valid variant to run. Use -h for help.")
|
246
|
-
print("Running the full application by default.")
|
247
|
-
window = MotorControlApp(client=client) # , config=CONFIG_DEFAULT)
|
248
|
-
|
249
|
-
window.show()
|
250
|
-
sys.exit(app.exec())
|