bec-widgets 0.64.2__py3-none-any.whl → 0.65.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## v0.65.1 (2024-06-20)
4
+
5
+ ### Fix
6
+
7
+ * fix: prevent segfault by closing the QCoreApplication, if any ([`fa344a5`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/fa344a5799b07a2d8ace63cc7010b69bc4ed6f1d))
8
+
9
+ ## v0.65.0 (2024-06-20)
10
+
11
+ ### Feature
12
+
13
+ * feat(device_input): DeviceLineEdit with QCompleter added ([`50e41ff`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/50e41ff26160ec26d77feb6d519e4dad902a9b9b))
14
+
15
+ * feat(device_combobox): DeviceInputBase and DeviceComboBox added ([`430b282`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/430b282039806e3fbc6cf98e958861a065760620))
16
+
17
+ ### Fix
18
+
19
+ * fix(device_input_base): bug with setting config and overwriting default device and filter ([`d79f7e9`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/d79f7e9ccde03dc77819ca556c79736d30f7821a))
20
+
21
+ ### Test
22
+
23
+ * test(device_input): tests added ([`1a0a98a`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/1a0a98a45367db414bed813bbd346b3e1ae8d550))
24
+
3
25
  ## v0.64.2 (2024-06-19)
4
26
 
5
27
  ### Fix
@@ -119,8 +141,6 @@ This reverts commit abc6caa2d0b6141dfbe1f3d025f78ae14deddcb3 ([`fe04dd8`](https:
119
141
 
120
142
  * ci: fixed pylint-check ([`6b1d582`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/6b1d5827d6599f06a3acd316060a8d25f0686d54))
121
143
 
122
- * ci: cleanup ([`11173b9`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/11173b9c0a7dc4b36e35962042e5b86407da49f1))
123
-
124
144
  ### Feature
125
145
 
126
146
  * feat: added isort to bw-generate-cli ([`f0391f5`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/f0391f59c9eb0a51b693fccfe2e399e869d35dda))
@@ -147,22 +167,6 @@ This reverts commit abc6caa2d0b6141dfbe1f3d025f78ae14deddcb3 ([`fe04dd8`](https:
147
167
 
148
168
  * refactor(isort): added bec_widgets as known first party package ([`9c5a471`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/9c5a471234ed2928e4527b079436db2a807c5f6f))
149
169
 
150
- * refactor(dock): parent_dock_area changed to orig_area (native for pyqtgraph) ([`2b40602`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/2b40602bdc593ece0447ec926c2100414bd5cf67))
151
-
152
170
  ### Test
153
171
 
154
172
  * test: added missing pylint statement to header ([`f662985`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/f6629852ebc2b4ee239fa560cc310a5ae2627cf7))
155
-
156
- ## v0.59.1 (2024-06-07)
157
-
158
- ### Fix
159
-
160
- * fix(curve): set_color_map_z typo fixed in user access ([`e7838b0`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/e7838b0f2fc23b0a232ed7d68fbd7f3493a91b9e))
161
-
162
- ## v0.59.0 (2024-06-07)
163
-
164
- ### Ci
165
-
166
- * ci: merged additional tests to parallel matrix job ([`178fe4d`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/178fe4d2da3a959f7cd90e7ea0f47314dc1ef4ed))
167
-
168
- * ci: added webengine dependencies ([`2d79ef8`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/2d79ef8fe5e52c61f4a78782770377cd6b41958b))
PKG-INFO CHANGED
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bec_widgets
3
- Version: 0.64.2
3
+ Version: 0.65.1
4
4
  Summary: BEC Widgets
5
5
  Project-URL: Bug Tracker, https://gitlab.psi.ch/bec/bec_widgets/issues
6
6
  Project-URL: Homepage, https://gitlab.psi.ch/bec/bec_widgets
@@ -115,6 +115,9 @@ class BECDispatcher:
115
115
  def reset_singleton(cls):
116
116
  cls._instance = None
117
117
  cls._initialized = False
118
+ if cls.qapp:
119
+ cls.qapp.exit()
120
+ cls.qapp = None
118
121
 
119
122
  def connect_slot(
120
123
  self, slot: Callable, topics: Union[EndpointInfo, str, list[Union[EndpointInfo, str]]]
@@ -0,0 +1,2 @@
1
+ from .device_combobox.device_combobox import DeviceComboBox
2
+ from .device_line_edit.device_line_edit import DeviceLineEdit
@@ -0,0 +1,95 @@
1
+ from typing import TYPE_CHECKING
2
+
3
+ from qtpy.QtWidgets import QComboBox
4
+
5
+ from bec_widgets.widgets.device_inputs.device_input_base import DeviceInputBase, DeviceInputConfig
6
+
7
+ if TYPE_CHECKING:
8
+ from bec_widgets.widgets.device_inputs.device_input_base import DeviceInputConfig
9
+
10
+
11
+ class DeviceComboBox(DeviceInputBase, QComboBox):
12
+ """
13
+ Line edit widget for device input with autocomplete for device names.
14
+
15
+ Args:
16
+ parent: Parent widget.
17
+ client: BEC client object.
18
+ config: Device input configuration.
19
+ gui_id: GUI ID.
20
+ device_filter: Device filter, name of the device class.
21
+ default_device: Default device name.
22
+ arg_name: Argument name, can be used for the other widgets which has to call some other function in bec using correct argument names.
23
+ """
24
+
25
+ def __init__(
26
+ self,
27
+ parent=None,
28
+ client=None,
29
+ config: DeviceInputConfig = None,
30
+ gui_id: str | None = None,
31
+ device_filter: str | None = None,
32
+ default_device: str | None = None,
33
+ arg_name: str | None = None,
34
+ ):
35
+ super().__init__(client=client, config=config, gui_id=gui_id)
36
+ QComboBox.__init__(self, parent=parent)
37
+
38
+ self.populate_combobox()
39
+
40
+ if arg_name is not None:
41
+ self.config.arg_name = arg_name
42
+ if device_filter is not None:
43
+ self.set_device_filter(device_filter)
44
+ if default_device is not None:
45
+ self.set_default_device(default_device)
46
+
47
+ def set_device_filter(self, device_filter: str):
48
+ """
49
+ Set the device filter.
50
+
51
+ Args:
52
+ device_filter(str): Device filter, name of the device class.
53
+ """
54
+ super().set_device_filter(device_filter)
55
+ self.populate_combobox()
56
+
57
+ def set_default_device(self, default_device: str):
58
+ """
59
+ Set the default device.
60
+
61
+ Args:
62
+ default_device(str): Default device name.
63
+ """
64
+ super().set_default_device(default_device)
65
+ self.setCurrentText(default_device)
66
+
67
+ def populate_combobox(self):
68
+ """Populate the combobox with the devices."""
69
+ self.devices = self.get_device_list(self.config.device_filter)
70
+ self.clear()
71
+ self.addItems(self.devices)
72
+
73
+ def get_device(self) -> object:
74
+ """
75
+ Get the selected device object.
76
+
77
+ Returns:
78
+ object: Device object.
79
+ """
80
+ device_name = self.currentText()
81
+ device_obj = getattr(self.dev, device_name.lower(), None)
82
+ if device_obj is None:
83
+ raise ValueError(f"Device {device_name} is not found.")
84
+ return device_obj
85
+
86
+
87
+ if __name__ == "__main__": # pragma: no cover
88
+ import sys
89
+
90
+ from qtpy.QtWidgets import QApplication
91
+
92
+ app = QApplication(sys.argv)
93
+ w = DeviceComboBox(default_device="samx")
94
+ w.show()
95
+ sys.exit(app.exec_())
@@ -0,0 +1,120 @@
1
+ from __future__ import annotations
2
+
3
+ from bec_widgets.utils import BECConnector, ConnectionConfig
4
+
5
+
6
+ class DeviceInputConfig(ConnectionConfig):
7
+ device_filter: str | list[str] | None = None
8
+ default_device: str | None = None
9
+ arg_name: str | None = None
10
+
11
+
12
+ class DeviceInputBase(BECConnector):
13
+ """
14
+ Mixin class for device input widgets. This class provides methods to get the device list and device object based
15
+ on the current text of the widget.
16
+ """
17
+
18
+ def __init__(self, client=None, config=None, gui_id=None):
19
+ if config is None:
20
+ config = DeviceInputConfig(widget_class=self.__class__.__name__)
21
+ else:
22
+ if isinstance(config, dict):
23
+ config = DeviceInputConfig(**config)
24
+ self.config = config
25
+ super().__init__(client=client, config=config, gui_id=gui_id)
26
+
27
+ self.get_bec_shortcuts()
28
+ self._devices = []
29
+
30
+ @property
31
+ def devices(self) -> list[str]:
32
+ """
33
+ Get the list of devices.
34
+
35
+ Returns:
36
+ list[str]: List of devices.
37
+ """
38
+ return self._devices
39
+
40
+ @devices.setter
41
+ def devices(self, value: list[str]):
42
+ """
43
+ Set the list of devices.
44
+
45
+ Args:
46
+ value: List of devices.
47
+ """
48
+ self._devices = value
49
+
50
+ def set_device_filter(self, device_filter: str | list[str]):
51
+ """
52
+ Set the device filter.
53
+
54
+ Args:
55
+ device_filter(str): Device filter, name of the device class.
56
+ """
57
+ self.validate_device_filter(device_filter)
58
+ self.config.device_filter = device_filter
59
+
60
+ def set_default_device(self, default_device: str):
61
+ """
62
+ Set the default device.
63
+
64
+ Args:
65
+ default_device(str): Default device name.
66
+ """
67
+ self.validate_device(default_device)
68
+ self.config.default_device = default_device
69
+
70
+ def get_device_list(self, filter: str | list[str] | None = None) -> list[str]:
71
+ """
72
+ Get the list of device names based on the filter of current BEC client.
73
+
74
+ Args:
75
+ filter(str|None): Class name filter to apply on the device list.
76
+
77
+ Returns:
78
+ devices(list[str]): List of device names.
79
+ """
80
+ all_devices = self.dev.enabled_devices
81
+ if filter is not None:
82
+ self.validate_device_filter(filter)
83
+ if isinstance(filter, str):
84
+ filter = [filter]
85
+ devices = [device.name for device in all_devices if device.__class__.__name__ in filter]
86
+ else:
87
+ devices = [device.name for device in all_devices]
88
+ return devices
89
+
90
+ def get_available_filters(self):
91
+ """
92
+ Get the available device classes which can be used as filters.
93
+ """
94
+ all_devices = self.dev.enabled_devices
95
+ filters = {device.__class__.__name__ for device in all_devices}
96
+ return filters
97
+
98
+ def validate_device_filter(self, filter: str | list[str]) -> None:
99
+ """
100
+ Validate the device filter if the class name is present in the current BEC instance.
101
+
102
+ Args:
103
+ filter(str|list[str]): Class name to use as a device filter.
104
+ """
105
+ if isinstance(filter, str):
106
+ filter = [filter]
107
+ available_filters = self.get_available_filters()
108
+ for f in filter:
109
+ if f not in available_filters:
110
+ raise ValueError(f"Device filter {f} is not valid.")
111
+
112
+ def validate_device(self, device: str) -> None:
113
+ """
114
+ Validate the device if it is present in current BEC instance.
115
+
116
+ Args:
117
+ device(str): Device to validate.
118
+ """
119
+ if device not in self.get_device_list(self.config.device_filter):
120
+ raise ValueError(f"Device {device} is not valid.")
@@ -0,0 +1,102 @@
1
+ from typing import TYPE_CHECKING
2
+
3
+ from qtpy.QtWidgets import QCompleter, QLineEdit
4
+
5
+ from bec_widgets.widgets.device_inputs.device_input_base import DeviceInputBase, DeviceInputConfig
6
+
7
+ if TYPE_CHECKING:
8
+ from bec_widgets.widgets.device_inputs.device_input_base import DeviceInputConfig
9
+
10
+
11
+ class DeviceLineEdit(DeviceInputBase, QLineEdit):
12
+ """
13
+ Line edit widget for device input with autocomplete for device names.
14
+
15
+ Args:
16
+ parent: Parent widget.
17
+ client: BEC client object.
18
+ config: Device input configuration.
19
+ gui_id: GUI ID.
20
+ device_filter: Device filter, name of the device class.
21
+ default_device: Default device name.
22
+ arg_name: Argument name, can be used for the other widgets which has to call some other function in bec using correct argument names.
23
+ """
24
+
25
+ def __init__(
26
+ self,
27
+ parent=None,
28
+ client=None,
29
+ config: DeviceInputConfig = None,
30
+ gui_id: str | None = None,
31
+ device_filter: str | list[str] | None = None,
32
+ default_device: str | None = None,
33
+ arg_name: str | None = None,
34
+ ):
35
+ QLineEdit.__init__(self, parent=parent)
36
+ DeviceInputBase.__init__(self, client=client, config=config, gui_id=gui_id)
37
+
38
+ self.completer = QCompleter(self)
39
+ self.setCompleter(self.completer)
40
+ self.populate_completer()
41
+
42
+ if arg_name is not None:
43
+ self.config.arg_name = arg_name
44
+ if device_filter is not None:
45
+ self.set_device_filter(device_filter)
46
+ if default_device is not None:
47
+ self.set_default_device(default_device)
48
+
49
+ def set_device_filter(self, device_filter: str | list[str]):
50
+ """
51
+ Set the device filter.
52
+
53
+ Args:
54
+ device_filter (str | list[str]): Device filter, name of the device class.
55
+ """
56
+ super().set_device_filter(device_filter)
57
+ self.populate_completer()
58
+
59
+ def set_default_device(self, default_device: str):
60
+ """
61
+ Set the default device.
62
+
63
+ Args:
64
+ default_device (str): Default device name.
65
+ """
66
+ super().set_default_device(default_device)
67
+ self.setText(default_device)
68
+
69
+ def populate_completer(self):
70
+ """Populate the completer with the devices."""
71
+ self.devices = self.get_device_list(self.config.device_filter)
72
+ self.completer.setModel(self.create_completer_model(self.devices))
73
+
74
+ def create_completer_model(self, devices: list[str]):
75
+ """Create a model for the completer."""
76
+ from qtpy.QtCore import QStringListModel
77
+
78
+ return QStringListModel(devices, self)
79
+
80
+ def get_device(self) -> object:
81
+ """
82
+ Get the selected device object.
83
+
84
+ Returns:
85
+ object: Device object.
86
+ """
87
+ device_name = self.text()
88
+ device_obj = getattr(self.dev, device_name.lower(), None)
89
+ if device_obj is None:
90
+ raise ValueError(f"Device {device_name} is not found.")
91
+ return device_obj
92
+
93
+
94
+ if __name__ == "__main__": # pragma: no cover
95
+ import sys
96
+
97
+ from qtpy.QtWidgets import QApplication
98
+
99
+ app = QApplication(sys.argv)
100
+ w = DeviceLineEdit(default_device="samx")
101
+ w.show()
102
+ sys.exit(app.exec_())
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bec_widgets
3
- Version: 0.64.2
3
+ Version: 0.65.1
4
4
  Summary: BEC Widgets
5
5
  Project-URL: Bug Tracker, https://gitlab.psi.ch/bec/bec_widgets/issues
6
6
  Project-URL: Homepage, https://gitlab.psi.ch/bec/bec_widgets
@@ -2,11 +2,11 @@
2
2
  .gitlab-ci.yml,sha256=RnYDz4zKXjlqltTryprlB1s5vLXxI2-seW-Vb70NNF0,8162
3
3
  .pylintrc,sha256=OstrgmEyP0smNFBKoIN5_26-UmNZgMHnbjvAWX0UrLs,18535
4
4
  .readthedocs.yaml,sha256=aSOc277LqXcsTI6lgvm_JY80lMlr69GbPKgivua2cS0,603
5
- CHANGELOG.md,sha256=gdWwJkkkabxh0__ronVR5oEcKdBLe48mB-n7nnbdpGM,7226
5
+ CHANGELOG.md,sha256=u9BAc4xc3_nMPLeP5aIg3ATqou7bVR1R7_hgAUGrSPc,7328
6
6
  LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
7
- PKG-INFO,sha256=Z6RgAVNJsHWfv4TE1hUqn_18H1piEkQJ-6d3YhaF9C8,1302
7
+ PKG-INFO,sha256=GEUYErFIs0zNQSkwgY4-NnOnhVFMYV-WmoeYd8hn7J8,1302
8
8
  README.md,sha256=y4jB6wvArS7N8_iTbKWnSM_oRAqLA2GqgzUR-FMh5sU,2645
9
- pyproject.toml,sha256=8rX9Uc6IOFHLtleUKw-gtujmtl91yE17M62S8LiYvwg,2162
9
+ pyproject.toml,sha256=Y6WXGiwh0VCA1cS6B_ejQDD7dIv7nPXkzfN89PbBAJo,2162
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
@@ -32,7 +32,7 @@ bec_widgets/examples/motor_movement/motor_control_compilations.py,sha256=8rpA7a2
32
32
  bec_widgets/examples/motor_movement/motor_controller.ui,sha256=83XX6NGILwntoUIghvzWnMuGf80O8khK3SduVKTAEFM,29105
33
33
  bec_widgets/utils/__init__.py,sha256=B7OZ2ArjyFaGNh4XYIbk49agnYCz704ltuFSalLCjSA,481
34
34
  bec_widgets/utils/bec_connector.py,sha256=RxHJNF7JjtY5pRbTMu2eQTiRXvoyJ53QuTYxHjZba38,5357
35
- bec_widgets/utils/bec_dispatcher.py,sha256=3zzf7LXCWtxiroUuSdObGexuYfRoq0QY1i3hJ7GmbBE,5726
35
+ bec_widgets/utils/bec_dispatcher.py,sha256=tFRd-rfOpyijr1iCGq31kLUjHRr9Y_h2HYYEZKZCgvo,5803
36
36
  bec_widgets/utils/bec_table.py,sha256=nA2b8ukSeUfquFMAxGrUVOqdrzMoDYD6O_4EYbOG2zk,717
37
37
  bec_widgets/utils/colors.py,sha256=GYSDe0ZxsJSwxvuy-yG2BH17qlf_Sjq8dhDcyp9IhBI,8532
38
38
  bec_widgets/utils/container_utils.py,sha256=m3VUyAYmSWkEwApP9tBvKxPYVtc2kHw4toxIpMryJy4,1495
@@ -50,6 +50,12 @@ bec_widgets/widgets/__init__.py,sha256=6RE9Pot2ud6BNJc_ZKiE--U-lgVRUff2IVR91lPcC
50
50
  bec_widgets/widgets/buttons/__init__.py,sha256=74ucIRU6-anoqQ-zT7wbrysmxhg_3_04xGhN_kllNUI,48
51
51
  bec_widgets/widgets/buttons/stop_button/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
52
52
  bec_widgets/widgets/buttons/stop_button/stop_button.py,sha256=x4a7RvlMkHzOd05zKOGYkyTmBza7Me7jgOL9WIgA_c4,906
53
+ bec_widgets/widgets/device_inputs/__init__.py,sha256=BcWvcSASPh6YdDu5jfC48xqI2_iBj1epUt4doYJQHEs,122
54
+ bec_widgets/widgets/device_inputs/device_input_base.py,sha256=ew3G1WXX0srCOQ2uRSjYoK5zB-NBZ9EwwhO-rmR3K4M,3803
55
+ bec_widgets/widgets/device_inputs/device_combobox/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
56
+ bec_widgets/widgets/device_inputs/device_combobox/device_combobox.py,sha256=_XL40tD1AVuSMmjC2movK5tscZzxfRnKg3lyZbvE6ZE,2889
57
+ bec_widgets/widgets/device_inputs/device_line_edit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
58
+ bec_widgets/widgets/device_inputs/device_line_edit/device_line_edit.py,sha256=cvvFg9HS7yN9kn-lWI_Uvj_dq2xlqNhuDi21e73k2xo,3249
53
59
  bec_widgets/widgets/dock/__init__.py,sha256=B7foHt02gnhM7mFksa7GJVwT7n0j_JvYDCt6wc6XR5g,61
54
60
  bec_widgets/widgets/dock/dock.py,sha256=z3NtfdtP_UHrjTKwZEOuWvh6azaiuYaFuEc260V6Jgg,7601
55
61
  bec_widgets/widgets/dock/dock_area.py,sha256=9c_tLzyBRllLfc4H5o9-4bvasWp5hWe1NWg4mupXVtU,7911
@@ -143,7 +149,7 @@ tests/end-2-end/test_bec_dock_rpc_e2e.py,sha256=8iJz4lITspY7eHdSgy9YvGUGTu3fsSpe
143
149
  tests/end-2-end/test_bec_figure_rpc_e2e.py,sha256=zTbB_F4Fs-QG8KhMK24xfsrCQBgZUAguMk3KFdEdP2o,5095
144
150
  tests/end-2-end/test_rpc_register_e2e.py,sha256=3dfCnSvdcRO92pzHt9WlCTK0vzTKAvPtliEoEKrtuzQ,1604
145
151
  tests/unit_tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
146
- tests/unit_tests/client_mocks.py,sha256=ErrklY7446jXE2_XGKebs_a-2Pqif5ECOPvxVAKRZXY,4170
152
+ tests/unit_tests/client_mocks.py,sha256=R71MJSu8IEyxcJjaIWCPACO_wOfx2Uv_qkmFVVmv7EQ,4195
147
153
  tests/unit_tests/conftest.py,sha256=KrnktXPWmZhnKNue-xGWOLD1XGEvdz9Vf7V2eO3XQ3A,596
148
154
  tests/unit_tests/test_bec_connector.py,sha256=f2XXGGw3NoZLIUrDuZuEWwF_ttOYmmquCgUrV5XkIOY,1951
149
155
  tests/unit_tests/test_bec_dispatcher.py,sha256=rYPiRizHaswhGZw55IBMneDFxmPiCCLAZQBqjEkpdyY,3992
@@ -153,6 +159,8 @@ tests/unit_tests/test_bec_motor_map.py,sha256=AfD_9-x6VV3TPnkQgNfFYRndPHDsGx-a_Y
153
159
  tests/unit_tests/test_client_utils.py,sha256=eViJ1Tz-HX9TkMvQH6W8cO-c3_1I8bUc4_Yen6LOc0E,830
154
160
  tests/unit_tests/test_color_validation.py,sha256=csdvVKAohENZIRY-JQ97Hv-TShb1erj4oKMX7QRwo78,1883
155
161
  tests/unit_tests/test_crosshair.py,sha256=3OMAJ2ZaISYXMOtkXf1rPdy94vCr8njeLi6uHblBL9Q,5045
162
+ tests/unit_tests/test_device_input_base.py,sha256=HesN6jDY1msbPPFsu3-wTcAmA27y92zxIgzt7tDo7MY,2451
163
+ tests/unit_tests/test_device_input_widgets.py,sha256=TOtO4z2c_rBmVlB5KD9JvEkyK-GXn1usbM0f2Scjpgc,5875
156
164
  tests/unit_tests/test_generate_cli_client.py,sha256=adcMoXjWpFLVjpauCu0r31CMMibUY1LF1MMf8rO-6rw,2815
157
165
  tests/unit_tests/test_motor_control.py,sha256=NBekcGALo5mYkuyBJvBhvJkWiQDV82hI4GmsobRzjTI,20770
158
166
  tests/unit_tests/test_plot_base.py,sha256=Akr_JgglUCrtERtdtsMqWko_MLUYoAYRGzV2sum-YHo,3836
@@ -171,8 +179,8 @@ tests/unit_tests/test_configs/config_device_no_entry.yaml,sha256=hdvue9KLc_kfNzG
171
179
  tests/unit_tests/test_configs/config_scan.yaml,sha256=vo484BbWOjA_e-h6bTjSV9k7QaQHrlAvx-z8wtY-P4E,1915
172
180
  tests/unit_tests/test_msgs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
173
181
  tests/unit_tests/test_msgs/available_scans_message.py,sha256=m_z97hIrjHXXMa2Ex-UvsPmTxOYXfjxyJaGkIY6StTY,46532
174
- bec_widgets-0.64.2.dist-info/METADATA,sha256=Z6RgAVNJsHWfv4TE1hUqn_18H1piEkQJ-6d3YhaF9C8,1302
175
- bec_widgets-0.64.2.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
176
- bec_widgets-0.64.2.dist-info/entry_points.txt,sha256=OvoqiNzNF9bizFQNhbAmmdc_njHrnVewLE-Kl-u9sh0,115
177
- bec_widgets-0.64.2.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
178
- bec_widgets-0.64.2.dist-info/RECORD,,
182
+ bec_widgets-0.65.1.dist-info/METADATA,sha256=GEUYErFIs0zNQSkwgY4-NnOnhVFMYV-WmoeYd8hn7J8,1302
183
+ bec_widgets-0.65.1.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
184
+ bec_widgets-0.65.1.dist-info/entry_points.txt,sha256=OvoqiNzNF9bizFQNhbAmmdc_njHrnVewLE-Kl-u9sh0,115
185
+ bec_widgets-0.65.1.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
186
+ bec_widgets-0.65.1.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.64.2"
7
+ version = "0.65.1"
8
8
  description = "BEC Widgets"
9
9
  requires-python = ">=3.10"
10
10
  classifiers = [
@@ -47,6 +47,7 @@ class FakePositioner(FakeDevice):
47
47
  super().__init__(name, enabled)
48
48
  self.limits = limits if limits is not None else [0, 0]
49
49
  self.read_value = read_value
50
+ self.name = name
50
51
 
51
52
  def set_read_value(self, value):
52
53
  self.read_value = value
@@ -0,0 +1,66 @@
1
+ import pytest
2
+
3
+ from bec_widgets.widgets.device_inputs.device_input_base import DeviceInputBase
4
+
5
+ from .client_mocks import mocked_client
6
+
7
+
8
+ @pytest.fixture
9
+ def device_input_base(mocked_client):
10
+ widget = DeviceInputBase(client=mocked_client)
11
+ yield widget
12
+
13
+
14
+ def test_device_input_base_init(device_input_base):
15
+ assert device_input_base is not None
16
+ assert device_input_base.client is not None
17
+ assert isinstance(device_input_base, DeviceInputBase)
18
+ assert device_input_base.config.widget_class == "DeviceInputBase"
19
+ assert device_input_base.config.device_filter is None
20
+ assert device_input_base.config.default_device is None
21
+ assert device_input_base.devices == []
22
+
23
+
24
+ def test_device_input_base_init_with_config(mocked_client):
25
+ config = {
26
+ "widget_class": "DeviceInputBase",
27
+ "gui_id": "test_gui_id",
28
+ "device_filter": "FakePositioner",
29
+ "default_device": "samx",
30
+ }
31
+ widget = DeviceInputBase(client=mocked_client, config=config)
32
+ assert widget.config.gui_id == "test_gui_id"
33
+ assert widget.config.device_filter == "FakePositioner"
34
+ assert widget.config.default_device == "samx"
35
+
36
+
37
+ def test_device_input_base_set_device_filter(device_input_base):
38
+ device_input_base.set_device_filter("FakePositioner")
39
+ assert device_input_base.config.device_filter == "FakePositioner"
40
+
41
+
42
+ def test_device_input_base_set_device_filter_error(device_input_base):
43
+ with pytest.raises(ValueError) as excinfo:
44
+ device_input_base.set_device_filter("NonExistingClass")
45
+ assert "Device filter NonExistingClass is not in the device list." in str(excinfo.value)
46
+
47
+
48
+ def test_device_input_base_set_default_device(device_input_base):
49
+ device_input_base.set_default_device("samx")
50
+ assert device_input_base.config.default_device == "samx"
51
+
52
+
53
+ def test_device_input_base_set_default_device_error(device_input_base):
54
+ with pytest.raises(ValueError) as excinfo:
55
+ device_input_base.set_default_device("NonExistingDevice")
56
+ assert "Default device NonExistingDevice is not in the device list." in str(excinfo.value)
57
+
58
+
59
+ def test_device_input_base_get_device_list(device_input_base):
60
+ devices = device_input_base.get_device_list("FakePositioner")
61
+ assert devices == ["samx", "samy", "aptrx", "aptry"]
62
+
63
+
64
+ def test_device_input_base_get_filters(device_input_base):
65
+ filters = device_input_base.get_available_filters()
66
+ assert filters == {"FakePositioner", "FakeDevice"}
@@ -0,0 +1,176 @@
1
+ import pytest
2
+
3
+ from bec_widgets.widgets.device_inputs.device_combobox.device_combobox import DeviceComboBox
4
+ from bec_widgets.widgets.device_inputs.device_line_edit.device_line_edit import DeviceLineEdit
5
+
6
+ from .client_mocks import mocked_client
7
+
8
+
9
+ @pytest.fixture
10
+ def device_input_combobox(qtbot, mocked_client):
11
+ widget = DeviceComboBox(client=mocked_client)
12
+ qtbot.addWidget(widget)
13
+ qtbot.waitExposed(widget)
14
+ yield widget
15
+ widget.close()
16
+
17
+
18
+ @pytest.fixture
19
+ def device_input_combobox_with_config(qtbot, mocked_client):
20
+ config = {
21
+ "widget_class": "DeviceComboBox",
22
+ "gui_id": "test_gui_id",
23
+ "device_filter": "FakePositioner",
24
+ "default_device": "samx",
25
+ "arg_name": "test_arg_name",
26
+ }
27
+ widget = DeviceComboBox(client=mocked_client, config=config)
28
+ qtbot.addWidget(widget)
29
+ qtbot.waitExposed(widget)
30
+ yield widget
31
+ widget.close()
32
+
33
+
34
+ @pytest.fixture
35
+ def device_input_combobox_with_kwargs(qtbot, mocked_client):
36
+ widget = DeviceComboBox(
37
+ client=mocked_client,
38
+ gui_id="test_gui_id",
39
+ device_filter="FakePositioner",
40
+ default_device="samx",
41
+ arg_name="test_arg_name",
42
+ )
43
+ qtbot.addWidget(widget)
44
+ qtbot.waitExposed(widget)
45
+ yield widget
46
+ widget.close()
47
+
48
+
49
+ def test_device_input_combobox_init(device_input_combobox):
50
+ assert device_input_combobox is not None
51
+ assert device_input_combobox.client is not None
52
+ assert isinstance(device_input_combobox, DeviceComboBox)
53
+ assert device_input_combobox.config.widget_class == "DeviceComboBox"
54
+ assert device_input_combobox.config.device_filter is None
55
+ assert device_input_combobox.config.default_device is None
56
+ assert device_input_combobox.devices == [
57
+ "samx",
58
+ "samy",
59
+ "aptrx",
60
+ "aptry",
61
+ "gauss_bpm",
62
+ "gauss_adc1",
63
+ "gauss_adc2",
64
+ "gauss_adc3",
65
+ "bpm4i",
66
+ "bpm3a",
67
+ "bpm3i",
68
+ "eiger",
69
+ ]
70
+
71
+
72
+ def test_device_input_combobox_init_with_config(device_input_combobox_with_config):
73
+ assert device_input_combobox_with_config.config.gui_id == "test_gui_id"
74
+ assert device_input_combobox_with_config.config.device_filter == "FakePositioner"
75
+ assert device_input_combobox_with_config.config.default_device == "samx"
76
+ assert device_input_combobox_with_config.config.arg_name == "test_arg_name"
77
+
78
+
79
+ def test_device_input_combobox_init_with_kwargs(device_input_combobox_with_kwargs):
80
+ assert device_input_combobox_with_kwargs.config.gui_id == "test_gui_id"
81
+ assert device_input_combobox_with_kwargs.config.device_filter == "FakePositioner"
82
+ assert device_input_combobox_with_kwargs.config.default_device == "samx"
83
+ assert device_input_combobox_with_kwargs.config.arg_name == "test_arg_name"
84
+
85
+
86
+ def test_get_device_from_input_combobox_init(device_input_combobox):
87
+ device_input_combobox.setCurrentIndex(0)
88
+ device_text = device_input_combobox.currentText()
89
+ current_device = device_input_combobox.get_device()
90
+
91
+ assert current_device.name == device_text
92
+
93
+
94
+ @pytest.fixture
95
+ def device_input_line_edit(qtbot, mocked_client):
96
+ widget = DeviceLineEdit(client=mocked_client)
97
+ qtbot.addWidget(widget)
98
+ qtbot.waitExposed(widget)
99
+ yield widget
100
+ widget.close()
101
+
102
+
103
+ @pytest.fixture
104
+ def device_input_line_edit_with_config(qtbot, mocked_client):
105
+ config = {
106
+ "widget_class": "DeviceLineEdit",
107
+ "gui_id": "test_gui_id",
108
+ "device_filter": "FakePositioner",
109
+ "default_device": "samx",
110
+ "arg_name": "test_arg_name",
111
+ }
112
+ widget = DeviceLineEdit(client=mocked_client, config=config)
113
+ qtbot.addWidget(widget)
114
+ qtbot.waitExposed(widget)
115
+ yield widget
116
+ widget.close()
117
+
118
+
119
+ @pytest.fixture
120
+ def device_input_line_edit_with_kwargs(qtbot, mocked_client):
121
+ widget = DeviceLineEdit(
122
+ client=mocked_client,
123
+ gui_id="test_gui_id",
124
+ device_filter="FakePositioner",
125
+ default_device="samx",
126
+ arg_name="test_arg_name",
127
+ )
128
+ qtbot.addWidget(widget)
129
+ qtbot.waitExposed(widget)
130
+ yield widget
131
+ widget.close()
132
+
133
+
134
+ def test_device_input_line_edit_init(device_input_line_edit):
135
+ assert device_input_line_edit is not None
136
+ assert device_input_line_edit.client is not None
137
+ assert isinstance(device_input_line_edit, DeviceLineEdit)
138
+ assert device_input_line_edit.config.widget_class == "DeviceLineEdit"
139
+ assert device_input_line_edit.config.device_filter is None
140
+ assert device_input_line_edit.config.default_device is None
141
+ assert device_input_line_edit.devices == [
142
+ "samx",
143
+ "samy",
144
+ "aptrx",
145
+ "aptry",
146
+ "gauss_bpm",
147
+ "gauss_adc1",
148
+ "gauss_adc2",
149
+ "gauss_adc3",
150
+ "bpm4i",
151
+ "bpm3a",
152
+ "bpm3i",
153
+ "eiger",
154
+ ]
155
+
156
+
157
+ def test_device_input_line_edit_init_with_config(device_input_line_edit_with_config):
158
+ assert device_input_line_edit_with_config.config.gui_id == "test_gui_id"
159
+ assert device_input_line_edit_with_config.config.device_filter == "FakePositioner"
160
+ assert device_input_line_edit_with_config.config.default_device == "samx"
161
+ assert device_input_line_edit_with_config.config.arg_name == "test_arg_name"
162
+
163
+
164
+ def test_device_input_line_edit_init_with_kwargs(device_input_line_edit_with_kwargs):
165
+ assert device_input_line_edit_with_kwargs.config.gui_id == "test_gui_id"
166
+ assert device_input_line_edit_with_kwargs.config.device_filter == "FakePositioner"
167
+ assert device_input_line_edit_with_kwargs.config.default_device == "samx"
168
+ assert device_input_line_edit_with_kwargs.config.arg_name == "test_arg_name"
169
+
170
+
171
+ def test_get_device_from_input_line_edit_init(device_input_line_edit):
172
+ device_input_line_edit.setText("samx")
173
+ device_text = device_input_line_edit.text()
174
+ current_device = device_input_line_edit.get_device()
175
+
176
+ assert current_device.name == device_text