bec-widgets 0.104.0__py3-none-any.whl → 0.105.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.
Files changed (31) hide show
  1. CHANGELOG.md +12 -12
  2. PKG-INFO +1 -1
  3. bec_widgets/cli/client.py +30 -0
  4. bec_widgets/cli/client_utils.py +5 -4
  5. bec_widgets/cli/server.py +21 -9
  6. bec_widgets/examples/plugin_example_pyside/tictactoe.py +0 -1
  7. bec_widgets/utils/bec_connector.py +5 -4
  8. bec_widgets/utils/bec_dispatcher.py +9 -13
  9. bec_widgets/utils/bec_widget.py +4 -0
  10. bec_widgets/widgets/dap_combo_box/__init__.py +0 -0
  11. bec_widgets/widgets/dap_combo_box/dap_combo_box.py +185 -0
  12. bec_widgets/widgets/dap_combo_box/dap_combo_box.pyproject +1 -0
  13. bec_widgets/widgets/dap_combo_box/dap_combo_box_plugin.py +54 -0
  14. bec_widgets/widgets/dap_combo_box/register_dap_combo_box.py +15 -0
  15. bec_widgets/widgets/device_browser/device_item/device_item.py +4 -1
  16. bec_widgets/widgets/figure/figure.py +4 -1
  17. bec_widgets/widgets/figure/plots/image/image.py +4 -1
  18. bec_widgets/widgets/figure/plots/image/image_item.py +4 -1
  19. bec_widgets/widgets/figure/plots/motor_map/motor_map.py +5 -2
  20. bec_widgets/widgets/figure/plots/plot_base.py +4 -1
  21. bec_widgets/widgets/figure/plots/waveform/waveform.py +7 -4
  22. bec_widgets/widgets/figure/plots/waveform/waveform_curve.py +4 -2
  23. bec_widgets/widgets/ring_progress_bar/ring_progress_bar.py +8 -5
  24. bec_widgets/widgets/scan_control/scan_group_box.py +6 -1
  25. bec_widgets/widgets/waveform/waveform_widget.py +4 -2
  26. {bec_widgets-0.104.0.dist-info → bec_widgets-0.105.0.dist-info}/METADATA +1 -1
  27. {bec_widgets-0.104.0.dist-info → bec_widgets-0.105.0.dist-info}/RECORD +31 -26
  28. pyproject.toml +1 -1
  29. {bec_widgets-0.104.0.dist-info → bec_widgets-0.105.0.dist-info}/WHEEL +0 -0
  30. {bec_widgets-0.104.0.dist-info → bec_widgets-0.105.0.dist-info}/entry_points.txt +0 -0
  31. {bec_widgets-0.104.0.dist-info → bec_widgets-0.105.0.dist-info}/licenses/LICENSE +0 -0
CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## v0.105.0 (2024-09-04)
4
+
5
+ ### Feature
6
+
7
+ * feat: add dap_combobox ([`cc691d4`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/cc691d4039bde710e78f362d2f0e712f9e8f196f))
8
+
9
+ ### Refactor
10
+
11
+ * refactor: cleanup and renaming of slot/signals ([`0fd5cee`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/0fd5cee77611b6645326eaefa68455ea8de26597))
12
+
13
+ * refactor(logger): changed prints to logger calls ([`3a5d7d0`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/3a5d7d07966ab9b38ba33bda0bed38c30f500c66))
14
+
3
15
  ## v0.104.0 (2024-09-04)
4
16
 
5
17
  ### Documentation
@@ -143,15 +155,3 @@
143
155
  ### Refactor
144
156
 
145
157
  * refactor(icons): general app icon changed; jupyter app icon changed to material icon ([`5d73fe4`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/5d73fe455a568ad40a9fadc5ce6e249d782ad20d))
146
-
147
- * refactor: add option to select scan and hide arg bundle buttons ([`7dadab1`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/7dadab1f14aa41876ad39e8cdc7f7732248cc643))
148
-
149
- ## v0.99.10 (2024-08-29)
150
-
151
- ### Fix
152
-
153
- * fix(stop_button): queue logic scan changed to halt instead of abort and reset ([`4a89028`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/4a890281f7eaef02d0ec9f4c5bf080be11fe0fe3))
154
-
155
- ### Refactor
156
-
157
- * refactor(stop_button): stop button changed to QWidget and adapted for toolbar ([`097946f`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/097946fd688b8faf770e7cc0e689ea668206bc7a))
PKG-INFO CHANGED
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bec_widgets
3
- Version: 0.104.0
3
+ Version: 0.105.0
4
4
  Summary: BEC Widgets
5
5
  Project-URL: Bug Tracker, https://gitlab.psi.ch/bec/bec_widgets/issues
6
6
  Project-URL: Homepage, https://gitlab.psi.ch/bec/bec_widgets
bec_widgets/cli/client.py CHANGED
@@ -22,6 +22,7 @@ class Widgets(str, enum.Enum):
22
22
  BECQueue = "BECQueue"
23
23
  BECStatusBox = "BECStatusBox"
24
24
  BECWaveformWidget = "BECWaveformWidget"
25
+ DapComboBox = "DapComboBox"
25
26
  DarkModeButton = "DarkModeButton"
26
27
  DeviceBrowser = "DeviceBrowser"
27
28
  DeviceComboBox = "DeviceComboBox"
@@ -2312,6 +2313,35 @@ class BECWaveformWidget(RPCBase):
2312
2313
  """
2313
2314
 
2314
2315
 
2316
+ class DapComboBox(RPCBase):
2317
+ @rpc_call
2318
+ def select_y_axis(self, y_axis: str):
2319
+ """
2320
+ Receive update signal for the y axis.
2321
+
2322
+ Args:
2323
+ y_axis(str): Y axis.
2324
+ """
2325
+
2326
+ @rpc_call
2327
+ def select_x_axis(self, x_axis: str):
2328
+ """
2329
+ Receive update signal for the x axis.
2330
+
2331
+ Args:
2332
+ x_axis(str): X axis.
2333
+ """
2334
+
2335
+ @rpc_call
2336
+ def select_fit(self, fit_name: str | None):
2337
+ """
2338
+ Select current fit.
2339
+
2340
+ Args:
2341
+ default_device(str): Default device name.
2342
+ """
2343
+
2344
+
2315
2345
  class DarkModeButton(RPCBase):
2316
2346
  @rpc_call
2317
2347
  def toggle_dark_mode(self) -> "None":
@@ -80,7 +80,7 @@ def _get_output(process, logger) -> None:
80
80
  buf.clear()
81
81
  buf.append(remaining)
82
82
  except Exception as e:
83
- print(f"Error reading process output: {str(e)}")
83
+ logger.error(f"Error reading process output: {str(e)}")
84
84
 
85
85
 
86
86
  def _start_plot_process(gui_id: str, gui_class: type, config: dict | str, logger=None) -> None:
@@ -146,7 +146,7 @@ class BECGuiClientMixin:
146
146
  continue
147
147
  return ep.load()(gui=self)
148
148
  except Exception as e:
149
- print(f"Error loading auto update script from plugin: {str(e)}")
149
+ logger.error(f"Error loading auto update script from plugin: {str(e)}")
150
150
  return None
151
151
 
152
152
  @property
@@ -189,11 +189,12 @@ class BECGuiClientMixin:
189
189
  if self._process is None or self._process.poll() is not None:
190
190
  self._start_update_script()
191
191
  self._process, self._process_output_processing_thread = _start_plot_process(
192
- self._gui_id, self.__class__, self._client._service_config.config
192
+ self._gui_id, self.__class__, self._client._service_config.config, logger=logger
193
193
  )
194
194
  while not self.gui_is_alive():
195
195
  print("Waiting for GUI to start...")
196
196
  time.sleep(1)
197
+ logger.success(f"GUI started with id: {self._gui_id}")
197
198
 
198
199
  def close(self) -> None:
199
200
  """
@@ -226,7 +227,7 @@ class RPCBase:
226
227
  def __init__(self, gui_id: str = None, config: dict = None, parent=None) -> None:
227
228
  self._client = BECClient() # BECClient is a singleton; here, we simply get the instance
228
229
  self._config = config if config is not None else {}
229
- self._gui_id = gui_id if gui_id is not None else str(uuid.uuid4())
230
+ self._gui_id = gui_id if gui_id is not None else str(uuid.uuid4())[:5]
230
231
  self._parent = parent
231
232
  self._msg_wait_event = threading.Event()
232
233
  self._rpc_response = None
bec_widgets/cli/server.py CHANGED
@@ -53,9 +53,11 @@ class BECWidgetsCLIServer:
53
53
  self._heartbeat_timer.start(200)
54
54
 
55
55
  self.status = messages.BECStatus.RUNNING
56
+ logger.success(f"Server started with gui_id: {self.gui_id}")
56
57
 
57
58
  def on_rpc_update(self, msg: dict, metadata: dict):
58
59
  request_id = metadata.get("request_id")
60
+ logger.debug(f"Received RPC instruction: {msg}, metadata: {metadata}")
59
61
  try:
60
62
  obj = self.get_object_from_config(msg["parameter"])
61
63
  method = msg["action"]
@@ -63,9 +65,10 @@ class BECWidgetsCLIServer:
63
65
  kwargs = msg["parameter"].get("kwargs", {})
64
66
  res = self.run_rpc(obj, method, args, kwargs)
65
67
  except Exception as e:
66
- print(e)
68
+ logger.error(f"Error while executing RPC instruction: {e}")
67
69
  self.send_response(request_id, False, {"error": str(e)})
68
70
  else:
71
+ logger.debug(f"RPC instruction executed successfully: {res}")
69
72
  self.send_response(request_id, True, {"result": res})
70
73
 
71
74
  def send_response(self, request_id: str, accepted: bool, msg: dict):
@@ -113,6 +116,7 @@ class BECWidgetsCLIServer:
113
116
  return obj
114
117
 
115
118
  def emit_heartbeat(self):
119
+ logger.trace(f"Emitting heartbeat for {self.gui_id}")
116
120
  self.client.connector.set(
117
121
  MessageEndpoints.gui_heartbeat(self.gui_id),
118
122
  messages.StatusMessage(name=self.gui_id, status=self.status, info={}),
@@ -120,6 +124,7 @@ class BECWidgetsCLIServer:
120
124
  )
121
125
 
122
126
  def shutdown(self): # TODO not sure if needed when cleanup is done at level of BECConnector
127
+ logger.info(f"Shutting down server with gui_id: {self.gui_id}")
123
128
  self.status = messages.BECStatus.IDLE
124
129
  self._heartbeat_timer.stop()
125
130
  self.emit_heartbeat()
@@ -137,7 +142,8 @@ class SimpleFileLikeFromLogOutputFunc:
137
142
 
138
143
  def flush(self):
139
144
  lines, _, remaining = "".join(self._buffer).rpartition("\n")
140
- self._log_func(lines)
145
+ if lines:
146
+ self._log_func(lines)
141
147
  self._buffer = [remaining]
142
148
 
143
149
  def close(self):
@@ -155,12 +161,12 @@ def _start_server(gui_id: str, gui_class: Union[BECFigure, BECDockArea], config:
155
161
  # if no config is provided, use the default config
156
162
  service_config = ServiceConfig()
157
163
 
158
- bec_logger.configure(
159
- service_config.redis,
160
- QtRedisConnector,
161
- service_name="BECWidgetsCLIServer",
162
- service_config=service_config.service_config,
163
- )
164
+ # bec_logger.configure(
165
+ # service_config.redis,
166
+ # QtRedisConnector,
167
+ # service_name="BECWidgetsCLIServer",
168
+ # service_config=service_config.service_config,
169
+ # )
164
170
  server = BECWidgetsCLIServer(gui_id=gui_id, config=service_config, gui_class=gui_class)
165
171
  return server
166
172
 
@@ -175,6 +181,12 @@ def main():
175
181
 
176
182
  import bec_widgets
177
183
 
184
+ bec_logger.level = bec_logger.LOGLEVEL.DEBUG
185
+ if __name__ != "__main__":
186
+ # if not running as main, set the log level to critical
187
+ # pylint: disable=protected-access
188
+ bec_logger._stderr_log_level = bec_logger.LOGLEVEL.CRITICAL
189
+
178
190
  parser = argparse.ArgumentParser(description="BEC Widgets CLI Server")
179
191
  parser.add_argument("--id", type=str, help="The id of the server")
180
192
  parser.add_argument(
@@ -197,7 +209,7 @@ def main():
197
209
  )
198
210
  gui_class = BECFigure
199
211
 
200
- with redirect_stdout(SimpleFileLikeFromLogOutputFunc(logger.debug)):
212
+ with redirect_stdout(SimpleFileLikeFromLogOutputFunc(logger.info)):
201
213
  with redirect_stderr(SimpleFileLikeFromLogOutputFunc(logger.error)):
202
214
  app = QApplication(sys.argv)
203
215
  app.setApplicationName("BEC Figure")
@@ -16,7 +16,6 @@ class TicTacToe(QWidget): # pragma: no cover
16
16
  super().__init__(parent)
17
17
  self._state = DEFAULT_STATE
18
18
  self._turn_number = 0
19
- print("TicTac HERE !!!!!!")
20
19
 
21
20
  def minimumSizeHint(self):
22
21
  return QSize(200, 200)
@@ -6,7 +6,7 @@ import time
6
6
  import uuid
7
7
  from typing import Optional
8
8
 
9
- import yaml
9
+ from bec_lib.logger import bec_logger
10
10
  from bec_lib.utils.import_utils import lazy_import_from
11
11
  from pydantic import BaseModel, Field, field_validator
12
12
  from qtpy.QtCore import QObject, QRunnable, QThreadPool, Signal
@@ -17,6 +17,7 @@ from bec_widgets.qt_utils.error_popups import ErrorPopupUtility
17
17
  from bec_widgets.qt_utils.error_popups import SafeSlot as pyqtSlot
18
18
  from bec_widgets.utils.yaml_dialog import load_yaml, load_yaml_gui, save_yaml, save_yaml_gui
19
19
 
20
+ logger = bec_logger.logger
20
21
  BECDispatcher = lazy_import_from("bec_widgets.utils.bec_dispatcher", ("BECDispatcher",))
21
22
 
22
23
 
@@ -81,9 +82,9 @@ class BECConnector:
81
82
  # the function depends on BECClient, and BECDispatcher
82
83
  @pyqtSlot()
83
84
  def terminate(client=self.client, dispatcher=self.bec_dispatcher):
84
- print("Disconnecting", repr(dispatcher))
85
+ logger.info("Disconnecting", repr(dispatcher))
85
86
  dispatcher.disconnect_all()
86
- print("Shutting down BEC Client", repr(client))
87
+ logger.info("Shutting down BEC Client", repr(client))
87
88
  client.shutdown()
88
89
 
89
90
  BECConnector.EXIT_HANDLERS[self.client] = terminate
@@ -93,7 +94,7 @@ class BECConnector:
93
94
  self.config = config
94
95
  self.config.widget_class = self.__class__.__name__
95
96
  else:
96
- print(
97
+ logger.debug(
97
98
  f"No initial config found for {self.__class__.__name__}.\n"
98
99
  f"Initializing with default config."
99
100
  )
@@ -6,11 +6,14 @@ from typing import TYPE_CHECKING, Union
6
6
 
7
7
  import redis
8
8
  from bec_lib.client import BECClient
9
+ from bec_lib.logger import bec_logger
9
10
  from bec_lib.redis_connector import MessageObject, RedisConnector
10
11
  from bec_lib.service_config import ServiceConfig
11
12
  from qtpy.QtCore import QObject
12
13
  from qtpy.QtCore import Signal as pyqtSignal
13
14
 
15
+ logger = bec_logger.logger
16
+
14
17
  if TYPE_CHECKING:
15
18
  from bec_lib.endpoints import EndpointInfo
16
19
 
@@ -65,11 +68,6 @@ class QtRedisConnector(RedisConnector):
65
68
  cb(msg.content, msg.metadata)
66
69
 
67
70
 
68
- class BECClientWithoutLoggerInit(BECClient):
69
- def _initialize_logger(self):
70
- return
71
-
72
-
73
71
  class BECDispatcher:
74
72
  """Utility class to keep track of slots connected to a particular redis connector"""
75
73
 
@@ -94,24 +92,22 @@ class BECDispatcher:
94
92
  if not isinstance(config, ServiceConfig):
95
93
  # config is supposed to be a path
96
94
  config = ServiceConfig(config)
97
- self.client = BECClientWithoutLoggerInit(
98
- config=config, connector_cls=QtRedisConnector
99
- ) # , forced=True)
100
- else:
101
- self.client = BECClientWithoutLoggerInit(
102
- connector_cls=QtRedisConnector
103
- ) # , forced=True)
95
+ self.client = BECClient(
96
+ config=config, connector_cls=QtRedisConnector, name="BECWidgets"
97
+ )
104
98
  else:
105
99
  if self.client.started:
106
100
  # have to reinitialize client to use proper connector
101
+ logger.info("Shutting down BECClient to switch to QtRedisConnector")
107
102
  self.client.shutdown()
108
103
  self.client._BECClient__init_params["connector_cls"] = QtRedisConnector
109
104
 
110
105
  try:
111
106
  self.client.start()
112
107
  except redis.exceptions.ConnectionError:
113
- print("Could not connect to Redis, skipping start of BECClient.")
108
+ logger.warning("Could not connect to Redis, skipping start of BECClient.")
114
109
 
110
+ logger.success("Initialized BECDispatcher")
115
111
  self._initialized = True
116
112
 
117
113
  @classmethod
@@ -1,12 +1,15 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import darkdetect
4
+ from bec_lib.logger import bec_logger
4
5
  from qtpy.QtCore import Slot
5
6
  from qtpy.QtWidgets import QApplication, QWidget
6
7
 
7
8
  from bec_widgets.utils.bec_connector import BECConnector, ConnectionConfig
8
9
  from bec_widgets.utils.colors import set_theme
9
10
 
11
+ logger = bec_logger.logger
12
+
10
13
 
11
14
  class BECWidget(BECConnector):
12
15
  """Mixin class for all BEC widgets, to handle cleanup"""
@@ -54,6 +57,7 @@ class BECWidget(BECConnector):
54
57
  set_theme("light")
55
58
 
56
59
  if theme_update:
60
+ logger.debug(f"Subscribing to theme updates for {self.__class__.__name__}")
57
61
  self._connect_to_theme_change()
58
62
 
59
63
  def _connect_to_theme_change(self):
File without changes
@@ -0,0 +1,185 @@
1
+ """ Module for DapComboBox widget class to select a DAP model from a combobox. """
2
+
3
+ from bec_lib.logger import bec_logger
4
+ from qtpy.QtCore import Property, Signal, Slot
5
+ from qtpy.QtWidgets import QComboBox, QVBoxLayout, QWidget
6
+
7
+ from bec_widgets.utils.bec_widget import BECWidget
8
+
9
+ logger = bec_logger.logger
10
+
11
+
12
+ class DapComboBox(BECWidget, QWidget):
13
+ """
14
+ The DAPComboBox widget is an extension to the QComboBox with all avaialble DAP model from BEC.
15
+
16
+ Args:
17
+ parent: Parent widget.
18
+ client: BEC client object.
19
+ gui_id: GUI ID.
20
+ default: Default device name.
21
+ """
22
+
23
+ ICON_NAME = "data_exploration"
24
+
25
+ USER_ACCESS = ["select_y_axis", "select_x_axis", "select_fit_model"]
26
+
27
+ ### Signals ###
28
+ # Signal to emit a new dap_config: (x_axis, y_axis, fit_model). Can be used to add a new DAP process
29
+ # in the BECWaveformWidget using its add_dap method. The signal is emitted when the user selects a new
30
+ # fit model, but only if x_axis and y_axis are set.
31
+ new_dap_config = Signal(str, str, str)
32
+ # Signal to emit the name of the updated x_axis
33
+ x_axis_updated = Signal(str)
34
+ # Signal to emit the name of the updated y_axis
35
+ y_axis_updated = Signal(str)
36
+ # Signal to emit the name of the updated fit model
37
+ fit_model_updated = Signal(str)
38
+
39
+ def __init__(
40
+ self, parent=None, client=None, gui_id: str | None = None, default_fit: str | None = None
41
+ ):
42
+ super().__init__(client=client, gui_id=gui_id)
43
+ QWidget.__init__(self, parent=parent)
44
+ self.layout = QVBoxLayout(self)
45
+ self.fit_model_combobox = QComboBox(self)
46
+ self.layout.addWidget(self.fit_model_combobox)
47
+ self.layout.setContentsMargins(0, 0, 0, 0)
48
+ self._available_models = None
49
+ self._x_axis = None
50
+ self._y_axis = None
51
+ self.populate_fit_model_combobox()
52
+ self.fit_model_combobox.currentTextChanged.connect(self._update_current_fit)
53
+ # Set default fit model
54
+ self.select_default_fit(default_fit)
55
+
56
+ def select_default_fit(self, default_fit: str | None):
57
+ """Set the default fit model.
58
+
59
+ Args:
60
+ default_fit(str): Default fit model.
61
+ """
62
+ if self._validate_dap_model(default_fit):
63
+ self.select_fit_model(default_fit)
64
+ else:
65
+ self.select_fit_model("GaussianModel")
66
+
67
+ @property
68
+ def available_models(self):
69
+ """Available models property."""
70
+ return self._available_models
71
+
72
+ @available_models.setter
73
+ def available_models(self, available_models: list[str]):
74
+ """Set the available models.
75
+
76
+ Args:
77
+ available_models(list[str]): Available models.
78
+ """
79
+ self._available_models = available_models
80
+
81
+ @Property(str)
82
+ def x_axis(self):
83
+ """X axis property."""
84
+ return self._x_axis
85
+
86
+ @x_axis.setter
87
+ def x_axis(self, x_axis: str):
88
+ """Set the x axis.
89
+
90
+ Args:
91
+ x_axis(str): X axis.
92
+ """
93
+ # TODO add validator for x axis -> Positioner? or also device (must be monitored)!!
94
+ self._x_axis = x_axis
95
+ self.x_axis_updated.emit(x_axis)
96
+
97
+ @Property(str)
98
+ def y_axis(self):
99
+ """Y axis property."""
100
+ # TODO add validator for y axis -> Positioner & Device? Must be a monitored device!!
101
+ return self._y_axis
102
+
103
+ @y_axis.setter
104
+ def y_axis(self, y_axis: str):
105
+ """Set the y axis.
106
+
107
+ Args:
108
+ y_axis(str): Y axis.
109
+ """
110
+ self._y_axis = y_axis
111
+ self.y_axis_updated.emit(y_axis)
112
+
113
+ def _update_current_fit(self, fit_name: str):
114
+ """Update the current fit."""
115
+ self.fit_model_updated.emit(fit_name)
116
+ if self.x_axis is not None and self.y_axis is not None:
117
+ self.new_dap_config.emit(self._x_axis, self._y_axis, fit_name)
118
+
119
+ @Slot(str)
120
+ def select_x_axis(self, x_axis: str):
121
+ """Slot to update the x axis.
122
+
123
+ Args:
124
+ x_axis(str): X axis.
125
+ """
126
+ self.x_axis = x_axis
127
+
128
+ @Slot(str)
129
+ def select_y_axis(self, y_axis: str):
130
+ """Slot to update the y axis.
131
+
132
+ Args:
133
+ y_axis(str): Y axis.
134
+ """
135
+ self.y_axis = y_axis
136
+
137
+ @Slot(str)
138
+ def select_fit_model(self, fit_name: str | None):
139
+ """Slot to update the fit model.
140
+
141
+ Args:
142
+ default_device(str): Default device name.
143
+ """
144
+ if not self._validate_dap_model(fit_name):
145
+ raise ValueError(f"Fit {fit_name} is not valid.")
146
+ self.fit_model_combobox.setCurrentText(fit_name)
147
+
148
+ def populate_fit_model_combobox(self):
149
+ """Populate the fit_model_combobox with the devices."""
150
+ # pylint: disable=protected-access
151
+ self.available_models = [model for model in self.client.dap._available_dap_plugins.keys()]
152
+ self.fit_model_combobox.clear()
153
+ self.fit_model_combobox.addItems(self.available_models)
154
+
155
+ def _validate_dap_model(self, model: str | None) -> bool:
156
+ """Validate the DAP model.
157
+
158
+ Args:
159
+ model(str): Model name.
160
+ """
161
+ if model is None:
162
+ return False
163
+ if model not in self.available_models:
164
+ return False
165
+ return True
166
+
167
+
168
+ # pragma: no cover
169
+ def main():
170
+ """Main function to run the DapComboBox widget."""
171
+ import sys
172
+
173
+ from qtpy.QtWidgets import QApplication
174
+
175
+ from bec_widgets.utils.colors import set_theme
176
+
177
+ app = QApplication(sys.argv)
178
+ set_theme("auto")
179
+ widget = DapComboBox()
180
+ widget.show()
181
+ sys.exit(app.exec_())
182
+
183
+
184
+ if __name__ == "__main__":
185
+ main()
@@ -0,0 +1 @@
1
+ {'files': ['dap_combo_box.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
+
6
+ from bec_widgets.utils.bec_designer import designer_material_icon
7
+ from bec_widgets.widgets.dap_combo_box.dap_combo_box import DapComboBox
8
+
9
+ DOM_XML = """
10
+ <ui language='c++'>
11
+ <widget class='DapComboBox' name='dap_combo_box'>
12
+ </widget>
13
+ </ui>
14
+ """
15
+
16
+
17
+ class DapComboBoxPlugin(QDesignerCustomWidgetInterface): # pragma: no cover
18
+ def __init__(self):
19
+ super().__init__()
20
+ self._form_editor = None
21
+
22
+ def createWidget(self, parent):
23
+ t = DapComboBox(parent)
24
+ return t
25
+
26
+ def domXml(self):
27
+ return DOM_XML
28
+
29
+ def group(self):
30
+ return "BEC Selection Widgets"
31
+
32
+ def icon(self):
33
+ return designer_material_icon(DapComboBox.ICON_NAME)
34
+
35
+ def includeFile(self):
36
+ return "dap_combo_box"
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 "DapComboBox"
49
+
50
+ def toolTip(self):
51
+ return ""
52
+
53
+ def whatsThis(self):
54
+ return self.toolTip()
@@ -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.dap_combo_box.dap_combo_box_plugin import DapComboBoxPlugin
10
+
11
+ QPyDesignerCustomWidgetCollection.addCustomWidget(DapComboBoxPlugin())
12
+
13
+
14
+ if __name__ == "__main__": # pragma: no cover
15
+ main()
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  from typing import TYPE_CHECKING
4
4
 
5
+ from bec_lib.logger import bec_logger
5
6
  from qtpy.QtCore import QMimeData, Qt
6
7
  from qtpy.QtGui import QDrag
7
8
  from qtpy.QtWidgets import QHBoxLayout, QLabel, QWidget
@@ -9,6 +10,8 @@ from qtpy.QtWidgets import QHBoxLayout, QLabel, QWidget
9
10
  if TYPE_CHECKING:
10
11
  from qtpy.QtGui import QMouseEvent
11
12
 
13
+ logger = bec_logger.logger
14
+
12
15
 
13
16
  class DeviceItem(QWidget):
14
17
  def __init__(self, device: str) -> None:
@@ -37,7 +40,7 @@ class DeviceItem(QWidget):
37
40
  drag.exec_(Qt.MoveAction)
38
41
 
39
42
  def mouseDoubleClickEvent(self, event: QMouseEvent) -> None:
40
- print("Double Clicked")
43
+ logger.debug("Double Clicked")
41
44
  # TODO: Implement double click action for opening the device properties dialog
42
45
  return super().mouseDoubleClickEvent(event)
43
46
 
@@ -7,6 +7,7 @@ from typing import Literal, Optional
7
7
 
8
8
  import numpy as np
9
9
  import pyqtgraph as pg
10
+ from bec_lib.logger import bec_logger
10
11
  from pydantic import Field, ValidationError, field_validator
11
12
  from qtpy.QtCore import Signal as pyqtSignal
12
13
  from qtpy.QtWidgets import QWidget
@@ -20,6 +21,8 @@ from bec_widgets.widgets.figure.plots.motor_map.motor_map import BECMotorMap, Mo
20
21
  from bec_widgets.widgets.figure.plots.plot_base import BECPlotBase, SubplotConfig
21
22
  from bec_widgets.widgets.figure.plots.waveform.waveform import BECWaveform, Waveform1DConfig
22
23
 
24
+ logger = bec_logger.logger
25
+
23
26
 
24
27
  class FigureConfig(ConnectionConfig):
25
28
  """Configuration for BECFigure. Inheriting from ConnectionConfig widget_class and gui_id"""
@@ -179,7 +182,7 @@ class BECFigure(BECWidget, pg.GraphicsLayoutWidget):
179
182
  try:
180
183
  config = FigureConfig(**config)
181
184
  except ValidationError as e:
182
- print(f"Error in applying config: {e}")
185
+ logger.error(f"Error in applying config: {e}")
183
186
  return
184
187
  self.config = config
185
188
 
@@ -5,6 +5,7 @@ from typing import Any, Literal, Optional
5
5
 
6
6
  import numpy as np
7
7
  from bec_lib.endpoints import MessageEndpoints
8
+ from bec_lib.logger import bec_logger
8
9
  from pydantic import BaseModel, Field, ValidationError
9
10
  from qtpy.QtCore import QThread
10
11
  from qtpy.QtWidgets import QWidget
@@ -19,6 +20,8 @@ from bec_widgets.widgets.figure.plots.image.image_processor import (
19
20
  )
20
21
  from bec_widgets.widgets.figure.plots.plot_base import BECPlotBase, SubplotConfig
21
22
 
23
+ logger = bec_logger.logger
24
+
22
25
 
23
26
  class ImageConfig(SubplotConfig):
24
27
  images: dict[str, ImageItemConfig] = Field(
@@ -130,7 +133,7 @@ class BECImageShow(BECPlotBase):
130
133
  try:
131
134
  config = ImageConfig(**config)
132
135
  except ValidationError as e:
133
- print(f"Validation error when applying config to BECImageShow: {e}")
136
+ logger.error(f"Validation error when applying config to BECImageShow: {e}")
134
137
  return
135
138
  self.config = config
136
139
  self.plot_item.clear()
@@ -4,6 +4,7 @@ from typing import TYPE_CHECKING, Literal, Optional
4
4
 
5
5
  import numpy as np
6
6
  import pyqtgraph as pg
7
+ from bec_lib.logger import bec_logger
7
8
  from pydantic import Field
8
9
 
9
10
  from bec_widgets.utils import BECConnector, ConnectionConfig
@@ -12,6 +13,8 @@ from bec_widgets.widgets.figure.plots.image.image_processor import ImageStats, P
12
13
  if TYPE_CHECKING:
13
14
  from bec_widgets.widgets.figure.plots.image.image import BECImageShow
14
15
 
16
+ logger = bec_logger.logger
17
+
15
18
 
16
19
  class ImageItemConfig(ConnectionConfig):
17
20
  parent_id: Optional[str] = Field(None, description="The parent plot of the image.")
@@ -133,7 +136,7 @@ class BECImageItem(BECConnector, pg.ImageItem):
133
136
  if key in method_map:
134
137
  method_map[key](value)
135
138
  else:
136
- print(f"Warning: '{key}' is not a recognized property.")
139
+ logger.warning(f"Warning: '{key}' is not a recognized property.")
137
140
 
138
141
  def set_fft(self, enable: bool = False):
139
142
  """
@@ -6,6 +6,7 @@ from typing import Optional, Union
6
6
  import numpy as np
7
7
  import pyqtgraph as pg
8
8
  from bec_lib.endpoints import MessageEndpoints
9
+ from bec_lib.logger import bec_logger
9
10
  from pydantic import Field, ValidationError, field_validator
10
11
  from pydantic_core import PydanticCustomError
11
12
  from qtpy import QtCore, QtGui
@@ -17,6 +18,8 @@ from bec_widgets.utils import Colors, EntryValidator
17
18
  from bec_widgets.widgets.figure.plots.plot_base import BECPlotBase, SubplotConfig
18
19
  from bec_widgets.widgets.figure.plots.waveform.waveform import Signal, SignalData
19
20
 
21
+ logger = bec_logger.logger
22
+
20
23
 
21
24
  class MotorMapConfig(SubplotConfig):
22
25
  signals: Optional[Signal] = Field(None, description="Signals of the motor map")
@@ -101,7 +104,7 @@ class BECMotorMap(BECPlotBase):
101
104
  try:
102
105
  config = MotorMapConfig(**config)
103
106
  except ValidationError as e:
104
- print(f"Error in applying config: {e}")
107
+ logger.error(f"Error in applying config: {e}")
105
108
  return
106
109
 
107
110
  self.config = config
@@ -440,7 +443,7 @@ class BECMotorMap(BECPlotBase):
440
443
  return limits
441
444
  except AttributeError: # TODO maybe not needed, if no limits it returns [0,0]
442
445
  # If the motor doesn't have a 'limits' attribute, return a default value or raise a custom exception
443
- print(f"The device '{motor}' does not have defined limits.")
446
+ logger.error(f"The device '{motor}' does not have defined limits.")
444
447
  return None
445
448
 
446
449
  @Slot()
@@ -4,6 +4,7 @@ from typing import Literal, Optional
4
4
 
5
5
  import bec_qthemes
6
6
  import pyqtgraph as pg
7
+ from bec_lib.logger import bec_logger
7
8
  from pydantic import BaseModel, Field
8
9
  from qtpy.QtCore import Signal, Slot
9
10
  from qtpy.QtWidgets import QApplication, QWidget
@@ -11,6 +12,8 @@ from qtpy.QtWidgets import QApplication, QWidget
11
12
  from bec_widgets.utils import BECConnector, ConnectionConfig
12
13
  from bec_widgets.utils.crosshair import Crosshair
13
14
 
15
+ logger = bec_logger.logger
16
+
14
17
 
15
18
  class AxisConfig(BaseModel):
16
19
  title: Optional[str] = Field(None, description="The title of the axes.")
@@ -164,7 +167,7 @@ class BECPlotBase(BECConnector, pg.GraphicsLayout):
164
167
  if key in method_map:
165
168
  method_map[key](value)
166
169
  else:
167
- print(f"Warning: '{key}' is not a recognized property.")
170
+ logger.warning(f"Warning: '{key}' is not a recognized property.")
168
171
 
169
172
  def apply_axis_config(self):
170
173
  """Apply the axis configuration to the plot widget."""
@@ -8,6 +8,7 @@ import pyqtgraph as pg
8
8
  from bec_lib import messages
9
9
  from bec_lib.device import ReadoutPriority
10
10
  from bec_lib.endpoints import MessageEndpoints
11
+ from bec_lib.logger import bec_logger
11
12
  from pydantic import Field, ValidationError, field_validator
12
13
  from pyqtgraph.exporters import MatplotlibExporter
13
14
  from qtpy.QtCore import Signal as pyqtSignal
@@ -23,6 +24,8 @@ from bec_widgets.widgets.figure.plots.waveform.waveform_curve import (
23
24
  SignalData,
24
25
  )
25
26
 
27
+ logger = bec_logger.logger
28
+
26
29
 
27
30
  class Waveform1DConfig(SubplotConfig):
28
31
  color_palette: Optional[str] = Field(
@@ -139,7 +142,7 @@ class BECWaveform(BECPlotBase):
139
142
  try:
140
143
  config = Waveform1DConfig(**config)
141
144
  except ValidationError as e:
142
- print(f"Validation error when applying config to BECWaveform1D: {e}")
145
+ logger.error(f"Validation error when applying config to BECWaveform1D: {e}")
143
146
  return
144
147
 
145
148
  self.config = config
@@ -553,7 +556,7 @@ class BECWaveform(BECPlotBase):
553
556
  format="HEX",
554
557
  )[len(self.plot_item.curves)]
555
558
  )
556
- print(f"Color: {color}")
559
+ logger.info(f"Color: {color}")
557
560
 
558
561
  # Create curve by config
559
562
  curve_config = CurveConfig(
@@ -1291,7 +1294,7 @@ class BECWaveform(BECPlotBase):
1291
1294
  try:
1292
1295
  self.scan_id = self.queue.scan_storage.storage[scan_index].scan_id
1293
1296
  except IndexError:
1294
- print(f"Scan index {scan_index} out of range.")
1297
+ logger.error(f"Scan index {scan_index} out of range.")
1295
1298
  return
1296
1299
  elif scan_id is not None:
1297
1300
  self.scan_id = scan_id
@@ -1317,7 +1320,7 @@ class BECWaveform(BECPlotBase):
1317
1320
  except ImportError:
1318
1321
  pd = None
1319
1322
  if output == "pandas":
1320
- print(
1323
+ logger.warning(
1321
1324
  "Pandas is not installed. "
1322
1325
  "Please install pandas using 'pip install pandas'."
1323
1326
  "Output will be dictionary instead."
@@ -4,8 +4,8 @@ from typing import TYPE_CHECKING, Any, Literal, Optional
4
4
 
5
5
  import numpy as np
6
6
  import pyqtgraph as pg
7
+ from bec_lib.logger import bec_logger
7
8
  from pydantic import BaseModel, Field, field_validator
8
- from pydantic_core import PydanticCustomError
9
9
  from qtpy import QtCore
10
10
 
11
11
  from bec_widgets.utils import BECConnector, Colors, ConnectionConfig
@@ -13,6 +13,8 @@ from bec_widgets.utils import BECConnector, Colors, ConnectionConfig
13
13
  if TYPE_CHECKING:
14
14
  from bec_widgets.widgets.figure.plots.waveform import BECWaveform1D
15
15
 
16
+ logger = bec_logger.logger
17
+
16
18
 
17
19
  class SignalData(BaseModel):
18
20
  """The data configuration of a signal in the 1D waveform widget for x and y axis."""
@@ -177,7 +179,7 @@ class BECCurve(BECConnector, pg.PlotDataItem):
177
179
  if key in method_map:
178
180
  method_map[key](value)
179
181
  else:
180
- print(f"Warning: '{key}' is not a recognized property.")
182
+ logger.warning(f"Warning: '{key}' is not a recognized property.")
181
183
 
182
184
  def set_color(self, color: str, symbol_color: Optional[str] = None):
183
185
  """
@@ -4,6 +4,7 @@ from typing import Literal, Optional
4
4
 
5
5
  import pyqtgraph as pg
6
6
  from bec_lib.endpoints import MessageEndpoints
7
+ from bec_lib.logger import bec_logger
7
8
  from pydantic import Field, field_validator
8
9
  from pydantic_core import PydanticCustomError
9
10
  from qtpy import QtCore, QtGui
@@ -14,6 +15,8 @@ from bec_widgets.utils import Colors, ConnectionConfig, EntryValidator
14
15
  from bec_widgets.utils.bec_widget import BECWidget
15
16
  from bec_widgets.widgets.ring_progress_bar.ring import Ring, RingConfig
16
17
 
18
+ logger = bec_logger.logger
19
+
17
20
 
18
21
  class RingProgressBarConfig(ConnectionConfig):
19
22
  color_map: Optional[str] = Field(
@@ -38,7 +41,7 @@ class RingProgressBarConfig(ConnectionConfig):
38
41
  min_number_of_bars = values.data.get("min_number_of_bars", None)
39
42
  max_number_of_bars = values.data.get("max_number_of_bars", None)
40
43
  if min_number_of_bars is not None and max_number_of_bars is not None:
41
- print(
44
+ logger.info(
42
45
  f"Number of bars adjusted to be between defined min:{min_number_of_bars} and max:{max_number_of_bars} number of bars."
43
46
  )
44
47
  v = max(min_number_of_bars, min(v, max_number_of_bars))
@@ -318,7 +321,7 @@ class RingProgressBar(BECWidget, QWidget):
318
321
  ring = self._find_ring_by_index(ring_index)
319
322
  if isinstance(values, list):
320
323
  values = values[0]
321
- print(
324
+ logger.warning(
322
325
  f"Warning: Only a single value can be set for a single progress bar. Using the first value in the list {values}"
323
326
  )
324
327
  ring.set_value(values)
@@ -380,7 +383,7 @@ class RingProgressBar(BECWidget, QWidget):
380
383
  ring = self._find_ring_by_index(bar_index)
381
384
  if isinstance(widths, list):
382
385
  widths = widths[0]
383
- print(
386
+ logger.warning(
384
387
  f"Warning: Only a single line width can be set for a single progress bar. Using the first value in the list {widths}"
385
388
  )
386
389
  ring.set_line_width(widths)
@@ -487,7 +490,7 @@ class RingProgressBar(BECWidget, QWidget):
487
490
  for index, device in enumerate(devices):
488
491
  self._hook_readback(index, device, start[index], end[index])
489
492
  else:
490
- print(f"{instruction_type} not supported yet.")
493
+ logger.error(f"{instruction_type} not supported yet.")
491
494
 
492
495
  # elif instruction_type == "device_progress":
493
496
  # print("hook device_progress")
@@ -609,7 +612,7 @@ class RingProgressBar(BECWidget, QWidget):
609
612
  Calculate the minimum size of the widget.
610
613
  """
611
614
  if not self.config.rings:
612
- print("no rings to get size from setting size to 10x10")
615
+ logger.warning("no rings to get size from setting size to 10x10")
613
616
  return QSize(10, 10)
614
617
  ring_widths = [self.config.rings[i].line_width for i in range(self.config.num_bars)]
615
618
  total_width = sum(ring_widths) + self.config.gap * (self.config.num_bars - 1)
@@ -1,5 +1,6 @@
1
1
  from typing import Literal
2
2
 
3
+ from bec_lib.logger import bec_logger
3
4
  from qtpy.QtCore import Qt
4
5
  from qtpy.QtWidgets import (
5
6
  QCheckBox,
@@ -18,6 +19,8 @@ from qtpy.QtWidgets import (
18
19
  from bec_widgets.utils.widget_io import WidgetIO
19
20
  from bec_widgets.widgets.device_line_edit.device_line_edit import DeviceLineEdit
20
21
 
22
+ logger = bec_logger.logger
23
+
21
24
 
22
25
  class ScanArgType:
23
26
  DEVICE = "device"
@@ -191,7 +194,9 @@ class ScanGroupBox(QGroupBox):
191
194
  default = item.get("default", None)
192
195
  widget = self.WIDGET_HANDLER.get(item["type"], None)
193
196
  if widget is None:
194
- print(f"Unsupported annotation '{item['type']}' for parameter '{item['name']}'")
197
+ logger.error(
198
+ f"Unsupported annotation '{item['type']}' for parameter '{item['name']}'"
199
+ )
195
200
  continue
196
201
  if default == "_empty":
197
202
  default = None
@@ -5,6 +5,7 @@ from typing import Literal
5
5
 
6
6
  import numpy as np
7
7
  import pyqtgraph as pg
8
+ from bec_lib.logger import bec_logger
8
9
  from qtpy.QtCore import Signal
9
10
  from qtpy.QtWidgets import QVBoxLayout, QWidget
10
11
 
@@ -26,6 +27,8 @@ try:
26
27
  except ImportError:
27
28
  pd = None
28
29
 
30
+ logger = bec_logger.logger
31
+
29
32
 
30
33
  class BECWaveformWidget(BECWidget, QWidget):
31
34
  ICON_NAME = "show_chart"
@@ -340,7 +343,6 @@ class BECWaveformWidget(BECWidget, QWidget):
340
343
  x_entry: str | None = None,
341
344
  y_entry: str | None = None,
342
345
  color: str | None = None,
343
- # dap: str = "GaussianModel",
344
346
  validate_bec: bool = True,
345
347
  **kwargs,
346
348
  ) -> BECCurve:
@@ -425,7 +427,7 @@ class BECWaveformWidget(BECWidget, QWidget):
425
427
  except ImportError:
426
428
  pd = None
427
429
  if output == "pandas":
428
- print(
430
+ logger.warning(
429
431
  "Pandas is not installed. "
430
432
  "Please install pandas using 'pip install pandas'."
431
433
  "Output will be dictionary instead."
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bec_widgets
3
- Version: 0.104.0
3
+ Version: 0.105.0
4
4
  Summary: BEC Widgets
5
5
  Project-URL: Bug Tracker, https://gitlab.psi.ch/bec/bec_widgets/issues
6
6
  Project-URL: Homepage, https://gitlab.psi.ch/bec/bec_widgets
@@ -2,11 +2,11 @@
2
2
  .gitlab-ci.yml,sha256=Dc1iDjsc72UxdUtihx4uSZU0lrTQeR8hZwGx1MQBfKE,8432
3
3
  .pylintrc,sha256=eeY8YwSI74oFfq6IYIbCqnx3Vk8ZncKaatv96n_Y8Rs,18544
4
4
  .readthedocs.yaml,sha256=aSOc277LqXcsTI6lgvm_JY80lMlr69GbPKgivua2cS0,603
5
- CHANGELOG.md,sha256=56BXszrhvVmZ-ko-vL6XvL-n404_pI3WPFat9QBsGKw,7391
5
+ CHANGELOG.md,sha256=g_RZX5HUBV0m39MX5Y8FO-GeBRnh2Wt2fob7OVvKlZY,7294
6
6
  LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
7
- PKG-INFO,sha256=5uieac1rLNLfxfbqXF9q2AyKsrEM34ZR7Mp_zjJOcLg,1334
7
+ PKG-INFO,sha256=oeOXM8pekkxHvoDKlMGeTVyy__CKVPQW0zJqHpaimZs,1334
8
8
  README.md,sha256=Od69x-RS85Hph0-WwWACwal4yUd67XkEn4APEfHhHFw,2649
9
- pyproject.toml,sha256=2KA4GlcKlp8NhsbCE5skdf7xye1F8SaNHRy11G7Ikfs,2544
9
+ pyproject.toml,sha256=LYboSo9nhqhJ2QeWVBT_4QKioh4f-0AG8Hi1BfOhPTw,2544
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
@@ -22,12 +22,12 @@ bec_widgets/assets/status_icons/running.svg,sha256=nlc6rKh_f-uOxQSk0BkBNyWnPAJU5
22
22
  bec_widgets/assets/status_icons/warning.svg,sha256=CNx88p9kbDG51s9ztKf-cfYan4JdDBbk3-IFKfOOFlI,364
23
23
  bec_widgets/cli/__init__.py,sha256=d0Q6Fn44e7wFfLabDOBxpcJ1DPKWlFunGYDUBmO-4hA,22
24
24
  bec_widgets/cli/auto_updates.py,sha256=DwzRChcFIWPH2kCYvp8H7dXvyYSKGYv6LwCmK2sDR2E,5676
25
- bec_widgets/cli/client.py,sha256=Sajhkf2hQJICfMSsB3nGLW5X2y50jwK2ICXxLSS4RXI,78465
26
- bec_widgets/cli/client_utils.py,sha256=l35LtTkD7PdvVCckjMU8-y6f5a5pp1u6cFPpD-Dkvow,11713
25
+ bec_widgets/cli/client.py,sha256=_DAmHtAAZdRfRNzBztxb1tdx5uWjhZ0hFNntlufulUI,79062
26
+ bec_widgets/cli/client_utils.py,sha256=EdDfo3uuYAWtZiDGGu3_GPnl94FSLkNG2N_4I9FNfMc,11809
27
27
  bec_widgets/cli/generate_cli.py,sha256=Ea5px9KblUlcGg-1JbJBTIU7laGg2n8PM7Efw9WVVzM,5889
28
28
  bec_widgets/cli/rpc_register.py,sha256=QxXUZu5XNg00Yf5O3UHWOXg3-f_pzKjjoZYMOa-MOJc,2216
29
29
  bec_widgets/cli/rpc_wigdet_handler.py,sha256=6kQng2DyS6rhLJqSJ7xa0kdgSxp-35A2upcf833dJRE,1483
30
- bec_widgets/cli/server.py,sha256=I3gZ5xwygEOnL4ga3zOoD3jRUXNjPRop4u7a0emfejs,7921
30
+ bec_widgets/cli/server.py,sha256=IsWXMN3KUQJykk8QOQjdWoXedMQC7MaidHe3e4XZw4I,8617
31
31
  bec_widgets/examples/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
32
  bec_widgets/examples/general_app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
33
  bec_widgets/examples/general_app/general_app.py,sha256=PoFCTuA_1yqrpgthASpYFgH7JDUZTcXAPZ5h0e3XZfc,3053
@@ -39,7 +39,7 @@ bec_widgets/examples/plugin_example_pyside/__init__.py,sha256=47DEQpj8HBSa-_TImW
39
39
  bec_widgets/examples/plugin_example_pyside/main.py,sha256=zDP5wO7wb3BVsQ15HOCRT1nNmCujIVRvSXZ3Txje8L0,549
40
40
  bec_widgets/examples/plugin_example_pyside/registertictactoe.py,sha256=cVhBnP0qx5j9Jft-VeKvlTFE-bX58hbP45CX0f4r5pM,535
41
41
  bec_widgets/examples/plugin_example_pyside/taskmenuextension.pyproject,sha256=O_PSMFJlXxQuf55gIOfkpfZIZGpX8W1SfUVZ-mvtI_E,119
42
- bec_widgets/examples/plugin_example_pyside/tictactoe.py,sha256=byR7mTiIXFaA9igPTH04pzm0yfikNB5KgISwvNiRPd8,4940
42
+ bec_widgets/examples/plugin_example_pyside/tictactoe.py,sha256=s3rCurXloVcmMdzZiSzDS7Lgj0Qe6x8-wkxCeiXYX80,4904
43
43
  bec_widgets/examples/plugin_example_pyside/tictactoeplugin.py,sha256=MFMwONn4EZ3V8DboEG4I3BXpURE9JDbKB7XTzzfZl5w,1978
44
44
  bec_widgets/examples/plugin_example_pyside/tictactoetaskmenu.py,sha256=V6OVnBTS-60zjQ2FAs88Ldjm1MfoMROfiQZZu6Guav8,2379
45
45
  bec_widgets/qt_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -48,11 +48,11 @@ bec_widgets/qt_utils/redis_message_waiter.py,sha256=fvL_QgC0cTDv_FPJdRyp5AKjf401
48
48
  bec_widgets/qt_utils/settings_dialog.py,sha256=NhtzTer_xzlB2lLLrGklkI1QYLJEWQpJoZbCz4o5daI,3645
49
49
  bec_widgets/qt_utils/toolbar.py,sha256=QMXTbEFowVzbQzblXZVJcAhgd_zrqaqBISyd4QlPv1A,8576
50
50
  bec_widgets/utils/__init__.py,sha256=1930ji1Jj6dVuY81Wd2kYBhHYNV-2R0bN_L4o9zBj1U,533
51
- bec_widgets/utils/bec_connector.py,sha256=SivHKXVyNVqeu3kCXYEPpbleTVw8g1cW0FKq1QrQgco,9987
51
+ bec_widgets/utils/bec_connector.py,sha256=I9M_4g-_-WaMmhyXzChFCGXAElelx0mG6E1g0KvtEQs,10059
52
52
  bec_widgets/utils/bec_designer.py,sha256=Z3MeMju-KmTz8POtm23VQfp4rvtD2sF6eIOKQkl2F7w,4729
53
- bec_widgets/utils/bec_dispatcher.py,sha256=NkObWO_gRO9Uobz-fy0gVTZqQsbFRaKj6fbjYZoErFI,6400
53
+ bec_widgets/utils/bec_dispatcher.py,sha256=OFmkx9vOz4pA4Sdc14QreyDZ870QYskJ4B5daVVeYg4,6325
54
54
  bec_widgets/utils/bec_table.py,sha256=nA2b8ukSeUfquFMAxGrUVOqdrzMoDYD6O_4EYbOG2zk,717
55
- bec_widgets/utils/bec_widget.py,sha256=7KmIdWCa7skN1jTsQQkhOpu2PZmKMr98AMB1f_MZfv4,3179
55
+ bec_widgets/utils/bec_widget.py,sha256=PRI1cjR7P4BxJRVz_hCF_KZ-891UmP4eADtHsOnxPG0,3333
56
56
  bec_widgets/utils/colors.py,sha256=N3GbVBpExfC1m_dnYFDoua-iRLM90E5kTKVOIkZVmDM,12372
57
57
  bec_widgets/utils/container_utils.py,sha256=0wr3ZfuMiAFKCrQHVjxjw-Vuk8wsHdridqcjy2eY840,1531
58
58
  bec_widgets/utils/crosshair.py,sha256=8lik9k69WI2WMj5FGLbrKtny9duxqXUJAhpX8tHoyp0,11543
@@ -109,6 +109,11 @@ bec_widgets/widgets/colormap_selector/colormap_selector.pyproject,sha256=lHl9qml
109
109
  bec_widgets/widgets/colormap_selector/colormap_selector_plugin.py,sha256=c5Kk4do8vi0y1bC54zaihvBC55iXaVkc8UMaCQEPwyE,1388
110
110
  bec_widgets/widgets/colormap_selector/register_colormap_selector.py,sha256=bfw7RWmTmMLTLxGT-izSwcGtxGLKvL3jdivJw2z8oN4,512
111
111
  bec_widgets/widgets/console/console.py,sha256=NG0cBuqqPX4hC-sHhk_UEkT-nHhhN9Y7karJITPLzyo,17864
112
+ bec_widgets/widgets/dap_combo_box/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
113
+ bec_widgets/widgets/dap_combo_box/dap_combo_box.py,sha256=MmDsEFxSYJBG4R9ql_UF0K0OtnZCQMDTvKWxzPmFleA,5596
114
+ bec_widgets/widgets/dap_combo_box/dap_combo_box.pyproject,sha256=3TzD8j0F6UYw8TPwKxVDeXdobnYIRXNrAUrXzqWjk4M,31
115
+ bec_widgets/widgets/dap_combo_box/dap_combo_box_plugin.py,sha256=WVR8k10SESRFm-hQUrcUfgycuNu7HIcZqV--24nw-TU,1270
116
+ bec_widgets/widgets/dap_combo_box/register_dap_combo_box.py,sha256=RGFzFmldBwQjpKB7wbIxJU20uprjXtqCVnUkt0Zc7aA,477
112
117
  bec_widgets/widgets/dark_mode_button/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
113
118
  bec_widgets/widgets/dark_mode_button/dark_mode_button.py,sha256=ZvCDO_FWtEn6M1Jxaw8x8GifsulJc2NsaXNvLKAKBs0,3259
114
119
  bec_widgets/widgets/dark_mode_button/dark_mode_button.pyproject,sha256=Lbi9zb6HNlIq14k6hlzR-oz6PIFShBuF7QxE6d87d64,34
@@ -121,7 +126,7 @@ bec_widgets/widgets/device_browser/device_browser.ui,sha256=Dy_3oXArScP-_7hRI6nQ
121
126
  bec_widgets/widgets/device_browser/device_browser_plugin.py,sha256=tBUePEzhXN-_lgig4PxFjAu1CJXUOW1VBPNnB6FukMc,1290
122
127
  bec_widgets/widgets/device_browser/register_device_browser.py,sha256=LJ0ckrgUbU5yprhlrOtSQzymztKyb9zksMuFO4BKN6s,483
123
128
  bec_widgets/widgets/device_browser/device_item/__init__.py,sha256=VGY-uNVCnpcY-q-gijteB2N8KxFNgYR-qQ209MVu1QI,36
124
- bec_widgets/widgets/device_browser/device_item/device_item.py,sha256=MtiHM8JXalfNzWYwBj12u_SJidkSchbCy7iT1YZouec,1476
129
+ bec_widgets/widgets/device_browser/device_item/device_item.py,sha256=pnsLmxcsULrt2E-Afbnbx3_6dAx4MDjMT2r479eM2GE,1549
125
130
  bec_widgets/widgets/device_combobox/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
126
131
  bec_widgets/widgets/device_combobox/device_combo_box.pyproject,sha256=wI2eXR5ky_IM9-BCHJnH_9CEqYcZwIuLcgitSEr8OJU,40
127
132
  bec_widgets/widgets/device_combobox/device_combo_box_plugin.py,sha256=E4kR_EWo2Y5k4r-glbz4S1kHSDhlVdNjVBRLuMjS0hU,1410
@@ -139,20 +144,20 @@ bec_widgets/widgets/dock/dock_area.pyproject,sha256=URW0UrDXCnkzk80rbQmUMgF6Uqay
139
144
  bec_widgets/widgets/dock/dock_area_plugin.py,sha256=hfA1r13hmlXaDO6kzbk6vBlhVlGh2eSTXrnftjzZj0Q,1320
140
145
  bec_widgets/widgets/dock/register_dock_area.py,sha256=Yqd1mq6CcHwlxHZxX5EHKONy4P44nMm8pso-4X0tvJI,464
141
146
  bec_widgets/widgets/figure/__init__.py,sha256=3hGx_KOV7QHCYAV06aNuUgKq4QIYCjUTad-DrwkUaBM,44
142
- bec_widgets/widgets/figure/figure.py,sha256=kd7enVkT7df79HWzYjCzAZ1qF8jtlzqNfo7YWSHq4cc,28776
147
+ bec_widgets/widgets/figure/figure.py,sha256=IzQaV_9utjViJyjMydOa3-EJ9k-FVG2PTVm8_ENCbgY,28849
143
148
  bec_widgets/widgets/figure/plots/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
144
149
  bec_widgets/widgets/figure/plots/axis_settings.py,sha256=QxRpQwgfBr1H0HTjfOpiXi_-n8I0BaZhS8LRXNeVfFg,3544
145
150
  bec_widgets/widgets/figure/plots/axis_settings.ui,sha256=a2qIuK9lyi9HCyrSvPr6wxzmm1FymaWcpmyOhMIiFt8,11013
146
- bec_widgets/widgets/figure/plots/plot_base.py,sha256=mCrQS9itby4jnwUGCQXqTQzGnP-yLZoyqI2flQvXsuc,15135
151
+ bec_widgets/widgets/figure/plots/plot_base.py,sha256=wuX0HQ_yY7gueXYOm1U1DIDLw8P5a6GW6WrJkYbPf_A,15210
147
152
  bec_widgets/widgets/figure/plots/image/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
148
- bec_widgets/widgets/figure/plots/image/image.py,sha256=y2MqgJv6Njv-huDN_exn0Fq1rAh5vs_assKCKHgQH6I,24941
149
- bec_widgets/widgets/figure/plots/image/image_item.py,sha256=RljjbkqJEr2cKDlqj1j5GQ1h89jpqOV-OpFz1TbED8I,10937
153
+ bec_widgets/widgets/figure/plots/image/image.py,sha256=rq2zy-vwZLd3___rFRNEBnPFGKSu88T5T4ngrTkcbr0,25014
154
+ bec_widgets/widgets/figure/plots/image/image_item.py,sha256=DhlBbI-c8nVbJ8tREQhyNr8Qk4W6PXF0HgBhrIoYQPo,11012
150
155
  bec_widgets/widgets/figure/plots/image/image_processor.py,sha256=GeTtWjbldy6VejMwPGQgM-o3d6bmLglCjdoktu19xfA,5262
151
156
  bec_widgets/widgets/figure/plots/motor_map/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
152
- bec_widgets/widgets/figure/plots/motor_map/motor_map.py,sha256=wgARzsm98Y8SHPPwVp1LzNlXCxKEi6a8by8yYzIWsbY,18319
157
+ bec_widgets/widgets/figure/plots/motor_map/motor_map.py,sha256=AiDq4bmcEoj9PlkRQtHCk-5cwvOFGPBcfxPNNr8E53Y,18399
153
158
  bec_widgets/widgets/figure/plots/waveform/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
154
- bec_widgets/widgets/figure/plots/waveform/waveform.py,sha256=TDPtS4s0Kc-1KPidymxW1JPLwV77dqZHO316GYfzu08,51841
155
- bec_widgets/widgets/figure/plots/waveform/waveform_curve.py,sha256=FlQFKm4r2xSrV9TSP0SWuD3lfAUO3COUHxMYz7Xxs5E,8653
159
+ bec_widgets/widgets/figure/plots/waveform/waveform.py,sha256=52yf5wba5JtX5MM-KoKWSdx6Ltv_n4xHyI2yvm2euhs,51936
160
+ bec_widgets/widgets/figure/plots/waveform/waveform_curve.py,sha256=RUo4GfXwlaCei8BBvWBQF3IEB8h-KgpvaHur6JUvT6s,8682
156
161
  bec_widgets/widgets/image/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
157
162
  bec_widgets/widgets/image/bec_image_widget.pyproject,sha256=PHisdBo5_5UCApd27GkizzqgfdjsDx2bFZa_p9LiSW8,30
158
163
  bec_widgets/widgets/image/bec_image_widget_plugin.py,sha256=3nOHJTukHsEkaCLAivPHIY4qdshAj86LUKb5fYF3C-Y,1369
@@ -194,7 +199,7 @@ bec_widgets/widgets/positioner_box/register_positioner_control_line.py,sha256=MJ
194
199
  bec_widgets/widgets/ring_progress_bar/__init__.py,sha256=_uoJKnDM2YAeUBfwc5WLbIHSJj7zm_FAurSKP3WRaCw,47
195
200
  bec_widgets/widgets/ring_progress_bar/register_ring_progress_bar.py,sha256=uJrMhkuQi2PdWa0BwFJqjVXSkO-TXoyai4EQYOOe9t4,493
196
201
  bec_widgets/widgets/ring_progress_bar/ring.py,sha256=2pdEzETaJpvx4Dzyosq2YhnvDOEUvFnj_f9GfFKpG5Q,11159
197
- bec_widgets/widgets/ring_progress_bar/ring_progress_bar.py,sha256=2AVEaMkdbVJk9uIpbT6B7M9TYnrywgOxfpGkbkVksOI,24151
202
+ bec_widgets/widgets/ring_progress_bar/ring_progress_bar.py,sha256=KXzQGHsYtX50Ys_W4YzLSe77tF1e110CLtJBPuZ9F4E,24257
198
203
  bec_widgets/widgets/ring_progress_bar/ring_progress_bar.pyproject,sha256=ZNYDnKDu9pixrY2XrulAGdKZg-Ysa7q67O_X2tAA0fc,35
199
204
  bec_widgets/widgets/ring_progress_bar/ring_progress_bar_plugin.py,sha256=-rw9ZSThgAH0Ubbr3X-L5x-ZqMXUGnauyFb4OmfUvD4,1394
200
205
  bec_widgets/widgets/scan_control/__init__.py,sha256=IOfHl15vxb_uC6KN62-PeUzbBha_vQyqkkXbJ2HU674,38
@@ -202,7 +207,7 @@ bec_widgets/widgets/scan_control/register_scan_control.py,sha256=xUX2yR0-MaIMg9_
202
207
  bec_widgets/widgets/scan_control/scan_control.py,sha256=PVy_gqivO_Nut6ZxdOhgXfRyRPcQ92wSGOGY8duxXlE,18074
203
208
  bec_widgets/widgets/scan_control/scan_control.pyproject,sha256=eTgVDFKToIH8_BbJjM2RvbOLr7HnYoidX0SAHx640DM,30
204
209
  bec_widgets/widgets/scan_control/scan_control_plugin.py,sha256=7GaqmaRgbwIPjVoXcyKVDl8UpfqC2weViup-YFfzUsM,1270
205
- bec_widgets/widgets/scan_control/scan_group_box.py,sha256=ZGF5alvw4vK---6-zsVUzW-6dt7-V68EbzrGp5EL_RE,10377
210
+ bec_widgets/widgets/scan_control/scan_group_box.py,sha256=H2QQFvRlmpF-lilmRRNB-vsAcYQkDYhbHZo32hPRVr8,10488
206
211
  bec_widgets/widgets/spinner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
207
212
  bec_widgets/widgets/spinner/register_spinner_widget.py,sha256=_zCPjLh4M7NTSHP1Atdn6yu33zJ3LJkcBy3KOJ5eSVY,476
208
213
  bec_widgets/widgets/spinner/spinner.py,sha256=5LoRGuRvQmY1hUCt06P3DJjXqOVkFCszbNAXRmPzqlo,2628
@@ -232,7 +237,7 @@ bec_widgets/widgets/waveform/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NM
232
237
  bec_widgets/widgets/waveform/bec_waveform_widget.pyproject,sha256=GLD8GN9dXx9wNbtnevrxqqcwk7vKV-Uv8QYSycdaoaI,33
233
238
  bec_widgets/widgets/waveform/bec_waveform_widget_plugin.py,sha256=qSQTeCzIUn8rgDkjIM47Rr3-fqg1uk8rDf_lCoY9gZw,1402
234
239
  bec_widgets/widgets/waveform/register_bec_waveform_widget.py,sha256=qZHVZH_lP2hvzkG1Ra0EyrXlMeLkRCy0aceH-bfJ1cs,490
235
- bec_widgets/widgets/waveform/waveform_widget.py,sha256=PCkJMPVtmdCTaa2PucDM91vDyW49xta04Ri5oFhTOi4,22227
240
+ bec_widgets/widgets/waveform/waveform_widget.py,sha256=n6_8B4frmpZGGGx6eWntLsoL-CpJ0_Bca9oENWJTY0Y,22264
236
241
  bec_widgets/widgets/waveform/waveform_popups/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
237
242
  bec_widgets/widgets/waveform/waveform_popups/curve_dialog/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
238
243
  bec_widgets/widgets/waveform/waveform_popups/curve_dialog/curve_dialog.py,sha256=ApWv0n33TJBP59CQ4MUdyPRSiKfXjTdfui1IfwzFNjE,13172
@@ -244,8 +249,8 @@ bec_widgets/widgets/website/register_website_widget.py,sha256=LIQJpV9uqcBiPR9cEA
244
249
  bec_widgets/widgets/website/website.py,sha256=42pncCc_zI2eqeMArIurVmPUukRo5bTxa2h1Skah-io,3012
245
250
  bec_widgets/widgets/website/website_widget.pyproject,sha256=scOiV3cV1_BjbzpPzy2N8rIJL5P2qIZz8ObTJ-Uvdtg,25
246
251
  bec_widgets/widgets/website/website_widget_plugin.py,sha256=pz38_C2cZ0yvPPS02wdIPcmhFo_yiwUhflsASocAPQQ,1341
247
- bec_widgets-0.104.0.dist-info/METADATA,sha256=5uieac1rLNLfxfbqXF9q2AyKsrEM34ZR7Mp_zjJOcLg,1334
248
- bec_widgets-0.104.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
249
- bec_widgets-0.104.0.dist-info/entry_points.txt,sha256=3otEkCdDB9LZJuBLzG4pFLK5Di0CVybN_12IsZrQ-58,166
250
- bec_widgets-0.104.0.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
251
- bec_widgets-0.104.0.dist-info/RECORD,,
252
+ bec_widgets-0.105.0.dist-info/METADATA,sha256=oeOXM8pekkxHvoDKlMGeTVyy__CKVPQW0zJqHpaimZs,1334
253
+ bec_widgets-0.105.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
254
+ bec_widgets-0.105.0.dist-info/entry_points.txt,sha256=3otEkCdDB9LZJuBLzG4pFLK5Di0CVybN_12IsZrQ-58,166
255
+ bec_widgets-0.105.0.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
256
+ bec_widgets-0.105.0.dist-info/RECORD,,
pyproject.toml CHANGED
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "bec_widgets"
7
- version = "0.104.0"
7
+ version = "0.105.0"
8
8
  description = "BEC Widgets"
9
9
  requires-python = ">=3.10"
10
10
  classifiers = [