bec-widgets 0.79.1__py3-none-any.whl → 0.79.3__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,23 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## v0.79.3 (2024-07-05)
4
+
5
+ ### Fix
6
+
7
+ * fix: changed inheritance to adress qt designer bug in rendering ([`e403870`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/e403870874bd5e45840a034d6f1b3dd576d9c846))
8
+
9
+ * fix: add designer plugin classes ([`1586ce2`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/1586ce2d6cba2bb086b2ef596e724bb9e40ab4f2))
10
+
11
+ ### Refactor
12
+
13
+ * refactor: simplify logic in bec_status_box ([`576353c`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/576353cfe8c6fd64db561f0b6e2bc951300643d3))
14
+
15
+ ## v0.79.2 (2024-07-04)
16
+
17
+ ### Fix
18
+
19
+ * fix: overwrite closeEvent and call super class ([`bc0ef78`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/bc0ef7893ef100b71b62101c459655509b534a56))
20
+
3
21
  ## v0.79.1 (2024-07-03)
4
22
 
5
23
  ### Fix
@@ -129,23 +147,3 @@
129
147
  ### Test
130
148
 
131
149
  * test(bec_figure): tests for removing widgets with rpc e2e ([`a268caa`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/a268caaa30711fcc7ece542d24578d74cbf65c77))
132
-
133
- ## v0.74.0 (2024-06-25)
134
-
135
- ### Documentation
136
-
137
- * docs(becfigure): docs added ([`a51b15d`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/a51b15da3f5e83e0c897a0342bdb05b9c677a179))
138
-
139
- ### Feature
140
-
141
- * feat(waveform1d): dap LMFit model can be added to plot ([`1866ba6`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/1866ba66c8e3526661beb13fff3e13af6a0ae562))
142
-
143
- ### Test
144
-
145
- * test(waveform1d): dap e2e test added ([`7271b42`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/7271b422f98ef9264970d708811c414b69a644db))
146
-
147
- ## v0.73.2 (2024-06-25)
148
-
149
- ### Fix
150
-
151
- * fix(vscode): only run terminate if the process is still alive ([`7120f3e`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/7120f3e93b054b788f15e2d5bcd688e3c140c1ce))
PKG-INFO CHANGED
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bec_widgets
3
- Version: 0.79.1
3
+ Version: 0.79.3
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
@@ -5,15 +5,16 @@ The widget automatically updates the status of all running BEC services, and dis
5
5
  from __future__ import annotations
6
6
 
7
7
  import sys
8
+ from collections import defaultdict
9
+ from dataclasses import dataclass
8
10
  from typing import TYPE_CHECKING
9
11
 
10
12
  import qdarktheme
11
13
  from bec_lib.utils.import_utils import lazy_import_from
12
- from pydantic import BaseModel, Field, field_validator
13
14
  from qtpy.QtCore import QObject, QTimer, Signal, Slot
14
- from qtpy.QtWidgets import QTreeWidget, QTreeWidgetItem
15
+ from qtpy.QtWidgets import QHBoxLayout, QTreeWidget, QTreeWidgetItem, QWidget
15
16
 
16
- from bec_widgets.utils.bec_connector import BECConnector, ConnectionConfig
17
+ from bec_widgets.utils.bec_connector import BECConnector
17
18
  from bec_widgets.widgets.bec_status_box.status_item import StatusItem
18
19
 
19
20
  if TYPE_CHECKING:
@@ -23,45 +24,18 @@ if TYPE_CHECKING:
23
24
  BECStatus = lazy_import_from("bec_lib.messages", ("BECStatus",))
24
25
 
25
26
 
26
- class BECStatusBoxConfig(ConnectionConfig):
27
- pass
28
-
29
-
30
- class BECServiceInfoContainer(BaseModel):
27
+ @dataclass
28
+ class BECServiceInfoContainer:
31
29
  """Container to store information about the BEC services."""
32
30
 
33
31
  service_name: str
34
- status: BECStatus | str = Field(
35
- default="NOTCONNECTED",
36
- description="The status of the service. Can be any of the BECStatus names, or NOTCONNECTED.",
37
- )
32
+ status: str
38
33
  info: dict
39
34
  metrics: dict | None
40
- model_config: dict = {"validate_assignment": True}
41
-
42
- @field_validator("status")
43
- @classmethod
44
- def validate_status(cls, v):
45
- """Validate input for status. Accept BECStatus and NOTCONNECTED.
46
-
47
- Args:
48
- v (BECStatus | str): The input value.
49
-
50
- Returns:
51
- str: The validated status.
52
- """
53
- if v in list(BECStatus.__members__.values()):
54
- return v.name
55
- if v in list(BECStatus.__members__.keys()) or v == "NOTCONNECTED":
56
- return v
57
- raise ValueError(
58
- f"Status must be one of {BECStatus.__members__.values()} or 'NOTCONNECTED'. Input {v}"
59
- )
60
35
 
61
36
 
62
37
  class BECServiceStatusMixin(QObject):
63
- """A mixin class to update the service status, and metrics.
64
- It emits a signal 'services_update' when the service status is updated.
38
+ """Mixin to receive the latest service status from the BEC server and emit it via services_update signal.
65
39
 
66
40
  Args:
67
41
  client (BECClient): The client object to connect to the BEC server.
@@ -69,29 +43,26 @@ class BECServiceStatusMixin(QObject):
69
43
 
70
44
  services_update = Signal(dict, dict)
71
45
 
72
- def __init__(self, client: BECClient):
73
- super().__init__()
46
+ def __init__(self, parent, client: BECClient):
47
+ super().__init__(parent)
74
48
  self.client = client
75
49
  self._service_update_timer = QTimer()
76
50
  self._service_update_timer.timeout.connect(self._get_service_status)
77
51
  self._service_update_timer.start(1000)
78
52
 
79
53
  def _get_service_status(self):
80
- """Pull latest service and metrics updates from REDIS for all services, and emit both via 'services_update' signal."""
54
+ """Get the latest service status from the BEC server."""
81
55
  # pylint: disable=protected-access
82
56
  self.client._update_existing_services()
83
57
  self.services_update.emit(self.client._services_info, self.client._services_metric)
84
58
 
85
59
 
86
- class BECStatusBox(BECConnector, QTreeWidget):
87
- """A widget to display the status of different BEC services.
88
- This widget automatically updates the status of all running BEC services, and displays their status.
89
- Information about the individual services is collapsible, and double clicking on
90
- the individual service will display the metrics about the service.
60
+ class BECStatusBox(BECConnector, QWidget):
61
+ """An autonomous widget to display the status of BEC services.
91
62
 
92
63
  Args:
93
64
  parent Optional : The parent widget for the BECStatusBox. Defaults to None.
94
- service_name Optional(str): The name of the top service label. Defaults to "BEC Server".
65
+ box_name Optional(str): The name of the top service label. Defaults to "BEC Server".
95
66
  client Optional(BECClient): The client object to connect to the BEC server. Defaults to None
96
67
  config Optional(BECStatusBoxConfig | dict): The configuration for the status box. Defaults to None.
97
68
  gui_id Optional(str): The unique id for the widget. Defaults to None.
@@ -99,58 +70,67 @@ class BECStatusBox(BECConnector, QTreeWidget):
99
70
 
100
71
  CORE_SERVICES = ["DeviceServer", "ScanServer", "SciHub", "ScanBundler", "FileWriterManager"]
101
72
 
102
- service_update = Signal(dict)
73
+ service_update = Signal(BECServiceInfoContainer)
103
74
  bec_core_state = Signal(str)
104
75
 
105
76
  def __init__(
106
77
  self,
107
78
  parent=None,
108
- service_name: str = "BEC Server",
79
+ box_name: str = "BEC Server",
109
80
  client: BECClient = None,
110
- config: BECStatusBoxConfig | dict = None,
111
81
  bec_service_status_mixin: BECServiceStatusMixin = None,
112
82
  gui_id: str = None,
113
83
  ):
114
- if config is None:
115
- config = BECStatusBoxConfig(widget_class=self.__class__.__name__)
116
- else:
117
- if isinstance(config, dict):
118
- config = BECStatusBoxConfig(**config)
119
- super().__init__(client=client, config=config, gui_id=gui_id)
120
- QTreeWidget.__init__(self, parent=parent)
84
+ super().__init__(client=client, gui_id=gui_id)
85
+ QWidget.__init__(self, parent=parent)
86
+ self.tree = QTreeWidget(self)
87
+ self.layout = QHBoxLayout(self)
121
88
 
122
- self.service_name = service_name
123
- self.config = config
124
-
125
- self.bec_service_info_container = {}
126
- self.tree_items = {}
127
- self.tree_top_item = None
89
+ self.box_name = box_name
90
+ self.status_container = defaultdict(lambda: {"info": None, "item": None, "widget": None})
128
91
 
129
92
  if not bec_service_status_mixin:
130
- bec_service_status_mixin = BECServiceStatusMixin(client=self.client)
93
+ bec_service_status_mixin = BECServiceStatusMixin(self, client=self.client)
131
94
  self.bec_service_status = bec_service_status_mixin
132
95
 
133
96
  self.init_ui()
134
97
  self.bec_service_status.services_update.connect(self.update_service_status)
135
98
  self.bec_core_state.connect(self.update_top_item_status)
136
- self.itemDoubleClicked.connect(self.on_tree_item_double_clicked)
99
+ self.tree.itemDoubleClicked.connect(self.on_tree_item_double_clicked)
100
+ self.layout.addWidget(self.tree)
137
101
 
138
102
  def init_ui(self) -> None:
139
- """Initialize the UI for the status box, and add QTreeWidget as the basis for the status box."""
103
+ """Init the UI for the BECStatusBox widget, should only take place once."""
140
104
  self.init_ui_tree_widget()
141
- top_label = self._create_status_widget(self.service_name, status=BECStatus.IDLE)
142
- self.tree_top_item = QTreeWidgetItem()
143
- self.tree_top_item.setExpanded(True)
144
- self.tree_top_item.setDisabled(True)
145
- self.addTopLevelItem(self.tree_top_item)
146
- self.setItemWidget(self.tree_top_item, 0, top_label)
105
+ top_label = self._create_status_widget(self.box_name, status=BECStatus.IDLE)
106
+ tree_item = QTreeWidgetItem()
107
+ tree_item.setExpanded(True)
108
+ tree_item.setDisabled(True)
109
+ self.status_container[self.box_name].update({"item": tree_item, "widget": top_label})
110
+ self.tree.addTopLevelItem(tree_item)
111
+ self.tree.setItemWidget(tree_item, 0, top_label)
147
112
  self.service_update.connect(top_label.update_config)
113
+ self._initialized = True
114
+
115
+ def init_ui_tree_widget(self) -> None:
116
+ """Initialise the tree widget for the status box."""
117
+ self.tree.setHeaderHidden(True)
118
+ # TODO probably here is a problem still with setting the stylesheet
119
+ self.tree.setStyleSheet(
120
+ "QTreeWidget::item:!selected "
121
+ "{ "
122
+ "border: 1px solid gainsboro; "
123
+ "border-left: none; "
124
+ "border-top: none; "
125
+ "}"
126
+ "QTreeWidget::item:selected {}"
127
+ )
148
128
 
149
129
  def _create_status_widget(
150
130
  self, service_name: str, status=BECStatus, info: dict = None, metrics: dict = None
151
131
  ) -> StatusItem:
152
132
  """Creates a StatusItem (QWidget) for the given service, and stores all relevant
153
- information about the service in the bec_service_info_container.
133
+ information about the service in the status_container.
154
134
 
155
135
  Args:
156
136
  service_name (str): The name of the service.
@@ -163,16 +143,8 @@ class BECStatusBox(BECConnector, QTreeWidget):
163
143
  """
164
144
  if info is None:
165
145
  info = {}
166
- self._update_bec_service_container(service_name, status, info, metrics)
167
- item = StatusItem(
168
- parent=self,
169
- config={
170
- "service_name": service_name,
171
- "status": status.name,
172
- "info": info,
173
- "metrics": metrics,
174
- },
175
- )
146
+ self._update_status_container(service_name, status, info, metrics)
147
+ item = StatusItem(parent=self, config=self.status_container[service_name]["info"])
176
148
  return item
177
149
 
178
150
  @Slot(str)
@@ -183,30 +155,35 @@ class BECStatusBox(BECConnector, QTreeWidget):
183
155
  Args:
184
156
  status (BECStatus): The state of the core services.
185
157
  """
186
- self.bec_service_info_container[self.service_name].status = status
187
- self.service_update.emit(self.bec_service_info_container[self.service_name].model_dump())
158
+ self.status_container[self.box_name]["info"].status = status
159
+ self.service_update.emit(self.status_container[self.box_name]["info"])
188
160
 
189
- def _update_bec_service_container(
161
+ def _update_status_container(
190
162
  self, service_name: str, status: BECStatus, info: dict, metrics: dict = None
191
163
  ) -> None:
192
- """Update the bec_service_info_container with the newest status and metrics for the BEC service.
164
+ """Update the status_container with the newest status and metrics for the BEC service.
193
165
  If information about the service already exists, it will create a new entry.
194
166
 
195
167
  Args:
196
168
  service_name (str): The name of the service.
197
- service_info (StatusMessage): A class containing the service status.
198
- service_metric (ServiceMetricMessage): A class containing the service metrics.
169
+ status (BECStatus): The status of the service.
170
+ info (dict): The information about the service.
171
+ metrics (dict): The metrics of the service.
199
172
  """
200
- container = self.bec_service_info_container.get(service_name, None)
173
+ container = self.status_container[service_name].get("info", None)
174
+
201
175
  if container:
202
- container.status = status
176
+ container.status = status.name
203
177
  container.info = info
204
178
  container.metrics = metrics
205
179
  return
206
180
  service_info_item = BECServiceInfoContainer(
207
- service_name=service_name, status=status, info=info, metrics=metrics
181
+ service_name=service_name,
182
+ status=status.name if isinstance(status, BECStatus) else status,
183
+ info=info,
184
+ metrics=metrics,
208
185
  )
209
- self.bec_service_info_container.update({service_name: service_info_item})
186
+ self.status_container[service_name].update({"info": service_info_item})
210
187
 
211
188
  @Slot(dict, dict)
212
189
  def update_service_status(self, services_info: dict, services_metric: dict) -> None:
@@ -217,7 +194,7 @@ class BECStatusBox(BECConnector, QTreeWidget):
217
194
  services_info (dict): A dictionary containing the service status for all running BEC services.
218
195
  services_metric (dict): A dictionary containing the service metrics for all running BEC services.
219
196
  """
220
- checked = []
197
+ checked = [self.box_name]
221
198
  services_info = self.update_core_services(services_info, services_metric)
222
199
  checked.extend(self.CORE_SERVICES)
223
200
 
@@ -225,28 +202,19 @@ class BECStatusBox(BECConnector, QTreeWidget):
225
202
  checked.append(service_name)
226
203
  metric_msg = services_metric.get(service_name, None)
227
204
  metrics = metric_msg.metrics if metric_msg else None
228
- if service_name in self.tree_items:
229
- self._update_bec_service_container(
230
- service_name=service_name, status=msg.status, info=msg.info, metrics=metrics
231
- )
232
- self.service_update.emit(self.bec_service_info_container[service_name].model_dump())
205
+ if service_name in self.status_container:
206
+ if not msg:
207
+ self.add_tree_item(service_name, "NOTCONNECTED", {}, metrics)
208
+ continue
209
+ self._update_status_container(service_name, msg.status, msg.info, metrics)
210
+ self.service_update.emit(self.status_container[service_name]["info"])
233
211
  continue
234
212
 
235
- item_widget = self._create_status_widget(
236
- service_name=service_name, status=msg.status, info=msg.info, metrics=metrics
237
- )
238
- item = QTreeWidgetItem()
239
- item.setDisabled(True)
240
- self.service_update.connect(item_widget.update_config)
241
- self.tree_top_item.addChild(item)
242
- self.setItemWidget(item, 0, item_widget)
243
- self.tree_items.update({service_name: (item, item_widget)})
244
-
213
+ self.add_tree_item(service_name, msg.status, msg.info, metrics)
245
214
  self.check_redundant_tree_items(checked)
246
215
 
247
216
  def update_core_services(self, services_info: dict, services_metric: dict) -> dict:
248
- """Method to process status and metrics updates of core services (stored in CORE_SERVICES).
249
- If a core services is not connected, it should not be removed from the status widget
217
+ """Update the core services of BEC, and emit the updated status to the BECStatusBox.
250
218
 
251
219
  Args:
252
220
  services_info (dict): A dictionary containing the service status of different services.
@@ -255,28 +223,28 @@ class BECStatusBox(BECConnector, QTreeWidget):
255
223
  Returns:
256
224
  dict: The services_info dictionary after removing the info updates related to the CORE_SERVICES
257
225
  """
258
- bec_core_state = "RUNNING"
226
+ core_state = BECStatus.RUNNING
259
227
  for service_name in sorted(self.CORE_SERVICES):
260
228
  metric_msg = services_metric.get(service_name, None)
261
229
  metrics = metric_msg.metrics if metric_msg else None
262
- if service_name not in services_info:
263
- self.bec_service_info_container[service_name].status = "NOTCONNECTED"
264
- bec_core_state = "ERROR"
265
- else:
266
- msg = services_info.pop(service_name)
267
- self._update_bec_service_container(
268
- service_name=service_name, status=msg.status, info=msg.info, metrics=metrics
269
- )
270
- bec_core_state = (
271
- "RUNNING" if (msg.status.value > 1 and bec_core_state == "RUNNING") else "ERROR"
272
- )
273
-
274
- if service_name in self.tree_items:
275
- self.service_update.emit(self.bec_service_info_container[service_name].model_dump())
230
+ msg = services_info.pop(service_name, None)
231
+ if service_name not in self.status_container:
232
+ if not msg:
233
+ self.add_tree_item(service_name, "NOTCONNECTED", {}, metrics)
234
+ continue
235
+ self.add_tree_item(service_name, msg.status, msg.info, metrics)
276
236
  continue
277
- self.add_tree_item(service_name, msg.status, msg.info, metrics)
237
+ if not msg:
238
+ self.status_container[service_name]["info"].status = "NOTCONNECTED"
239
+ core_state = None
240
+ else:
241
+ self._update_status_container(service_name, msg.status, msg.info, metrics)
242
+ if core_state:
243
+ core_state = msg.status if msg.status.value < core_state.value else core_state
278
244
 
279
- self.bec_core_state.emit(bec_core_state)
245
+ self.service_update.emit(self.status_container[service_name]["info"])
246
+
247
+ self.bec_core_state.emit(core_state.name if core_state else "NOTCONNECTED")
280
248
  return services_info
281
249
 
282
250
  def check_redundant_tree_items(self, checked: list) -> None:
@@ -285,11 +253,12 @@ class BECStatusBox(BECConnector, QTreeWidget):
285
253
  Args:
286
254
  checked (list): A list of services that are currently running.
287
255
  """
288
- to_be_deleted = [key for key in self.tree_items if key not in checked]
256
+ to_be_deleted = [key for key in self.status_container if key not in checked]
289
257
 
290
258
  for key in to_be_deleted:
291
- item, _ = self.tree_items.pop(key)
292
- self.tree_top_item.removeChild(item)
259
+ obj = self.status_container.pop(key)
260
+ item = obj["item"]
261
+ self.status_container[self.box_name]["item"].removeChild(item)
293
262
 
294
263
  def add_tree_item(
295
264
  self, service_name: str, status: BECStatus, info: dict = None, metrics: dict = None
@@ -298,30 +267,16 @@ class BECStatusBox(BECConnector, QTreeWidget):
298
267
 
299
268
  Args:
300
269
  service_name (str): The name of the service.
301
- service_status_msg (StatusMessage): The status of the service.
270
+ status (BECStatus): The status of the service.
271
+ info (dict): The information about the service.
302
272
  metrics (dict): The metrics of the service.
303
273
  """
304
- item_widget = self._create_status_widget(
305
- service_name=service_name, status=status, info=info, metrics=metrics
306
- )
274
+ item_widget = self._create_status_widget(service_name, status, info, metrics)
307
275
  item = QTreeWidgetItem()
308
276
  self.service_update.connect(item_widget.update_config)
309
- self.tree_top_item.addChild(item)
310
- self.setItemWidget(item, 0, item_widget)
311
- self.tree_items.update({service_name: (item, item_widget)})
312
-
313
- def init_ui_tree_widget(self) -> None:
314
- """Initialise the tree widget for the status box."""
315
- self.setHeaderHidden(True)
316
- self.setStyleSheet(
317
- "QTreeWidget::item:!selected "
318
- "{ "
319
- "border: 1px solid gainsboro; "
320
- "border-left: none; "
321
- "border-top: none; "
322
- "}"
323
- "QTreeWidget::item:selected {}"
324
- )
277
+ self.status_container[self.box_name]["item"].addChild(item)
278
+ self.tree.setItemWidget(item, 0, item_widget)
279
+ self.status_container[service_name].update({"item": item, "widget": item_widget})
325
280
 
326
281
  @Slot(QTreeWidgetItem, int)
327
282
  def on_tree_item_double_clicked(self, item: QTreeWidgetItem, column: int) -> None:
@@ -331,13 +286,18 @@ class BECStatusBox(BECConnector, QTreeWidget):
331
286
  item (QTreeWidgetItem): The item that was double clicked.
332
287
  column (int): The column that was double clicked.
333
288
  """
334
- for _, (tree_item, status_widget) in self.tree_items.items():
335
- if tree_item == item:
336
- status_widget.show_popup()
289
+ for _, objects in self.status_container.items():
290
+ if objects["item"] == item:
291
+ objects["widget"].show_popup()
337
292
 
338
293
  def closeEvent(self, event):
294
+ """Upon closing the widget, clean up the BECStatusBox and the QWidget.
295
+
296
+ Args:
297
+ event: The close event.
298
+ """
339
299
  super().cleanup()
340
- QTreeWidget().closeEvent(event)
300
+ super().closeEvent(event)
341
301
 
342
302
 
343
303
  def main():
@@ -0,0 +1 @@
1
+ {'files': ['bec_status_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
+ from qtpy.QtGui import QIcon
6
+
7
+ from bec_widgets.widgets.bec_status_box.bec_status_box import BECStatusBox
8
+
9
+ DOM_XML = """
10
+ <ui language='c++'>
11
+ <widget class='BECStatusBox' name='bec_status_box'>
12
+ </widget>
13
+ </ui>
14
+ """
15
+
16
+
17
+ class BECStatusBoxPlugin(QDesignerCustomWidgetInterface): # pragma: no cover
18
+ def __init__(self):
19
+ super().__init__()
20
+ self._form_editor = None
21
+
22
+ def createWidget(self, parent):
23
+ t = BECStatusBox(parent)
24
+ return t
25
+
26
+ def domXml(self):
27
+ return DOM_XML
28
+
29
+ def group(self):
30
+ return ""
31
+
32
+ def icon(self):
33
+ return QIcon()
34
+
35
+ def includeFile(self):
36
+ return "bec_status_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 "BECStatusBox"
49
+
50
+ def toolTip(self):
51
+ return "An autonomous widget to display the status of BEC services."
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.bec_status_box.bec_status_box_plugin import BECStatusBoxPlugin
10
+
11
+ QPyDesignerCustomWidgetCollection.addCustomWidget(BECStatusBoxPlugin())
12
+
13
+
14
+ if __name__ == "__main__": # pragma: no cover
15
+ main()
@@ -2,17 +2,12 @@
2
2
  The widget is bound to be used with the BECStatusBox widget."""
3
3
 
4
4
  import enum
5
- import sys
6
5
  from datetime import datetime
7
6
 
8
- import qdarktheme
9
7
  from bec_lib.utils.import_utils import lazy_import_from
10
- from pydantic import Field
11
8
  from qtpy.QtCore import Qt, Slot
12
9
  from qtpy.QtWidgets import QDialog, QHBoxLayout, QLabel, QStyle, QVBoxLayout, QWidget
13
10
 
14
- from bec_widgets.utils.bec_connector import ConnectionConfig
15
-
16
11
  # TODO : Put normal imports back when Pydantic gets faster
17
12
  BECStatus = lazy_import_from("bec_lib.messages", ("BECStatus",))
18
13
 
@@ -27,39 +22,29 @@ class IconsEnum(enum.Enum):
27
22
  NOTCONNECTED = "SP_TitleBarContextHelpButton"
28
23
 
29
24
 
30
- class StatusWidgetConfig(ConnectionConfig):
31
- """Configuration class for the status item widget."""
32
-
33
- service_name: str
34
- status: str
35
- info: dict
36
- metrics: dict | None
37
- icon_size: tuple = Field(default=(24, 24), description="The size of the icon in the widget.")
38
- font_size: int = Field(16, description="The font size of the text in the widget.")
39
-
40
-
41
25
  class StatusItem(QWidget):
42
26
  """A widget to display the status of a service.
43
27
 
44
28
  Args:
45
29
  parent: The parent widget.
46
- config (dict): The configuration for the service.
30
+ config (dict): The configuration for the service, must be a BECServiceInfoContainer.
47
31
  """
48
32
 
49
- def __init__(self, parent=None, config: dict = None):
50
- if config is None:
51
- config = StatusWidgetConfig(widget_class=self.__class__.__name__)
52
- else:
53
- if isinstance(config, dict):
54
- config = StatusWidgetConfig(**config)
55
- self.config = config
33
+ def __init__(self, parent: QWidget = None, config=None):
56
34
  QWidget.__init__(self, parent=parent)
35
+ if config is None:
36
+ # needed because we need parent to be the first argument for QT Designer
37
+ raise ValueError(
38
+ "Please initialize the StatusItem with a BECServiceInfoContainer for config, received None."
39
+ )
40
+ self.config = config
57
41
  self.parent = parent
58
42
  self.layout = None
59
- self.config = config
60
- self._popup_label_ref = {}
61
43
  self._label = None
62
44
  self._icon = None
45
+ self.icon_size = (24, 24)
46
+
47
+ self._popup_label_ref = {}
63
48
  self.init_ui()
64
49
 
65
50
  def init_ui(self) -> None:
@@ -74,23 +59,21 @@ class StatusItem(QWidget):
74
59
  self.update_ui()
75
60
 
76
61
  @Slot(dict)
77
- def update_config(self, config: dict) -> None:
78
- """Update the configuration of the status item widget.
79
- This method is invoked from the parent widget.
80
- The UI values are later updated based on the new configuration.
62
+ def update_config(self, config) -> None:
63
+ """Update the config of the status item widget.
81
64
 
82
65
  Args:
83
- config (dict): Config updates from parent widget.
66
+ config (dict): Config updates from parent widget, must be a BECServiceInfoContainer.
84
67
  """
85
- if config["service_name"] != self.config.service_name:
68
+ if self.config is None or config.service_name != self.config.service_name:
86
69
  return
87
- self.config.status = config["status"]
88
- self.config.info = config["info"]
89
- self.config.metrics = config["metrics"]
70
+ self.config = config
90
71
  self.update_ui()
91
72
 
92
73
  def update_ui(self) -> None:
93
74
  """Update the UI of the labels, and popup dialog."""
75
+ if self.config is None:
76
+ return
94
77
  self.set_text()
95
78
  self.set_status()
96
79
  self._set_popup_text()
@@ -99,8 +82,8 @@ class StatusItem(QWidget):
99
82
  """Set the text of the QLabel basae on the config."""
100
83
  service = self.config.service_name
101
84
  status = self.config.status
102
- if "BECClient" in service.split("/"):
103
- service = service.split("/")[0] + "/..." + service.split("/")[1][-4:]
85
+ if len(service.split("/")) > 1 and service.split("/")[0].startswith("BEC"):
86
+ service = service.split("/", maxsplit=1)[0] + "/..." + service.split("/")[1][-4:]
104
87
  if status == "NOTCONNECTED":
105
88
  status = "NOT CONNECTED"
106
89
  text = f"{service} is {status}"
@@ -110,7 +93,7 @@ class StatusItem(QWidget):
110
93
  """Set the status icon for the status item widget."""
111
94
  icon_name = IconsEnum[self.config.status].value
112
95
  icon = self.style().standardIcon(getattr(QStyle.StandardPixmap, icon_name))
113
- self._icon.setPixmap(icon.pixmap(*self.config.icon_size))
96
+ self._icon.setPixmap(icon.pixmap(*self.icon_size))
114
97
  self._icon.setAlignment(Qt.AlignmentFlag.AlignRight)
115
98
 
116
99
  def show_popup(self) -> None:
@@ -153,19 +136,3 @@ class StatusItem(QWidget):
153
136
  def _cleanup_popup_label(self) -> None:
154
137
  """Cleanup the popup label."""
155
138
  self._popup_label_ref.clear()
156
-
157
-
158
- def main():
159
- """Run the status item widget."""
160
- # pylint: disable=import-outside-toplevel
161
- from qtpy.QtWidgets import QApplication
162
-
163
- app = QApplication(sys.argv)
164
- qdarktheme.setup_theme("auto")
165
- main_window = StatusItem()
166
- main_window.show()
167
- sys.exit(app.exec())
168
-
169
-
170
- if __name__ == "__main__":
171
- main()
@@ -89,4 +89,4 @@ class DeviceComboBox(DeviceInputBase, QComboBox):
89
89
 
90
90
  def closeEvent(self, event):
91
91
  super().cleanup()
92
- QComboBox().closeEvent(event)
92
+ return QComboBox.closeEvent(self, event)
@@ -101,4 +101,4 @@ class DeviceLineEdit(DeviceInputBase, QLineEdit):
101
101
 
102
102
  def closeEvent(self, event):
103
103
  super().cleanup()
104
- QLineEdit().closeEvent(event)
104
+ return QLineEdit.closeEvent(self, event)
@@ -198,7 +198,7 @@ class ScanControl(BECConnector, QWidget):
198
198
 
199
199
  def closeEvent(self, event):
200
200
  self.cleanup()
201
- QWidget().closeEvent(event)
201
+ return QWidget.closeEvent(self, event)
202
202
 
203
203
 
204
204
  # Application example
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bec_widgets
3
- Version: 0.79.1
3
+ Version: 0.79.3
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=pdwhbdbQLOlVP8AEjRkhj-O5AHC8UPasmD5XhuA-D7U,7105
5
+ CHANGELOG.md,sha256=GC_r9Byw1xBscFwof_pEjhjMkmOLnQYybtibbMQDv84,7091
6
6
  LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
7
- PKG-INFO,sha256=C2PR5dChRiBjSv03ME8uiQ3J1i5ub8NbNj6eZ-4fOPM,1427
7
+ PKG-INFO,sha256=KNOSryTtLS3GCT2Zw_6V5l9g4xxCSX_MAvinpePvrBU,1427
8
8
  README.md,sha256=y4jB6wvArS7N8_iTbKWnSM_oRAqLA2GqgzUR-FMh5sU,2645
9
- pyproject.toml,sha256=v8po8TOQhWpG4Lkc1vYj4ObhtbSXQmxVSxF2GqcR23M,2403
9
+ pyproject.toml,sha256=UakMzJgq7Qf9K_YagOPPzsfhPEg0FO_KedOKoZEDT9c,2403
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
@@ -64,8 +64,11 @@ bec_widgets/widgets/bec_queue/bec_queue.pyproject,sha256=VhoNmAv1DQUl9dg7dELyf5i
64
64
  bec_widgets/widgets/bec_queue/bec_queue_plugin.py,sha256=hDJm8Zd_GIDw2R8VYn4ytwrHVCmJUjC9dGDMae2omU0,1175
65
65
  bec_widgets/widgets/bec_queue/register_bec_queue.py,sha256=XnwtUSa1asK1b80knKWodcyX9qJy4DnKsQL_FoDfZy4,463
66
66
  bec_widgets/widgets/bec_status_box/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
67
- bec_widgets/widgets/bec_status_box/bec_status_box.py,sha256=twWugYlGVSl9ziSbjeB75BZwuruXFszRoOlN0d79Gnk,14523
68
- bec_widgets/widgets/bec_status_box/status_item.py,sha256=wPkDm0GCGNXXpy3rR_Ljaxy0ZHeiiYcrWFqEntZnz4E,5869
67
+ bec_widgets/widgets/bec_status_box/bec_status_box.py,sha256=mZqwwMCkSqgHToQI6qBUElhP4PFzCgi_Fo5jr9qj1DU,13023
68
+ bec_widgets/widgets/bec_status_box/bec_status_box.pyproject,sha256=JWtx3Csfn2h7ODtk10HtyBNLf6tFIqyU6g04rMWOO1U,32
69
+ bec_widgets/widgets/bec_status_box/bec_status_box_plugin.py,sha256=CNFIETpkORLQ9J3l91jefiRLJs5Ru3nsWIPoUwaRbB0,1242
70
+ bec_widgets/widgets/bec_status_box/register_bec_status_box.py,sha256=EiQITnkNw7IU7hE776wAeXro97eZd9XlsB9essgCebE,481
71
+ bec_widgets/widgets/bec_status_box/status_item.py,sha256=2SoMmgHL_MFnr7XiStFjLolHh0Vs3P68ZvP8kMIGc8w,5046
69
72
  bec_widgets/widgets/buttons/__init__.py,sha256=74ucIRU6-anoqQ-zT7wbrysmxhg_3_04xGhN_kllNUI,48
70
73
  bec_widgets/widgets/buttons/color_button/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
71
74
  bec_widgets/widgets/buttons/color_button/color_button.py,sha256=AJUMOQVLd4H39wzW2MJLhGAww7a1NtjivTkfexVhHHo,512
@@ -79,13 +82,13 @@ bec_widgets/widgets/console/console.py,sha256=EgKYlbW3NrRPoQwIr8x739sLd1IRBWkEy2
79
82
  bec_widgets/widgets/device_inputs/__init__.py,sha256=BcWvcSASPh6YdDu5jfC48xqI2_iBj1epUt4doYJQHEs,122
80
83
  bec_widgets/widgets/device_inputs/device_input_base.py,sha256=AP0Pgto87CKqgTuzrmFL3a7MOW9_qm1rmyiI2ZrvCOM,3839
81
84
  bec_widgets/widgets/device_inputs/device_combobox/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
82
- bec_widgets/widgets/device_inputs/device_combobox/device_combobox.py,sha256=S5QIDis1SKVVUH2bYgROE40xdMBCuoZAGuh5yW0OvU0,2815
85
+ bec_widgets/widgets/device_inputs/device_combobox/device_combobox.py,sha256=0IMwb7A2A9HosgYQXpzYbOj6iQAhoMSrOTTGYbhJyDc,2826
83
86
  bec_widgets/widgets/device_inputs/device_combobox/device_combobox.pyproject,sha256=AH6Oz_4aDCzsBbHWnCNK_ALvQ0Qwj-z24sUG1oNSK3I,75
84
87
  bec_widgets/widgets/device_inputs/device_combobox/device_combobox_plugin.py,sha256=VfbP0PrLwME8OB1bz1kVmy8vJCZDRONvas5j5cPyd08,1218
85
88
  bec_widgets/widgets/device_inputs/device_combobox/launch_device_combobox.py,sha256=jr9JJHtIPmbUNLpGLUESS_bYcITnbv-W3EdrZCHq2Rg,267
86
89
  bec_widgets/widgets/device_inputs/device_combobox/register_device_combobox.py,sha256=V6QcxBU9Lli4qy2Vhf9bFfpTsofsc-bT-_vEp0heBsM,518
87
90
  bec_widgets/widgets/device_inputs/device_line_edit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
88
- bec_widgets/widgets/device_inputs/device_line_edit/device_line_edit.py,sha256=147grp_zFMlYq4MiSffw9QULTD5hQWby7v7xf93-Oxk,3368
91
+ bec_widgets/widgets/device_inputs/device_line_edit/device_line_edit.py,sha256=DJbUvO5ewg-IG4-CgW69OSH3qvxd3bWuCGdy8q5NTrY,3379
89
92
  bec_widgets/widgets/device_inputs/device_line_edit/device_line_edit.pyproject,sha256=0GTk3WfNUHl-6tFEAY0pel5XBpVR0oyRX2BU-LNzVps,77
90
93
  bec_widgets/widgets/device_inputs/device_line_edit/device_line_edit_plugin.py,sha256=J1MNrtXkgBrwEsUXnf0pGRoNJ1g_OWqk-xafSpV4ot8,1239
91
94
  bec_widgets/widgets/device_inputs/device_line_edit/launch_device_line_edit.py,sha256=3sVZ-5Hoy1smhgBcnzO9SXHk5_oUEaWFnRfslXAW3_4,267
@@ -141,7 +144,7 @@ bec_widgets/widgets/ring_progress_bar/__init__.py,sha256=_uoJKnDM2YAeUBfwc5WLbIH
141
144
  bec_widgets/widgets/ring_progress_bar/ring.py,sha256=19zFj-6ZrIPLXYqvs5EPcrmDWnfnSLlEOmzJffL4d3A,11241
142
145
  bec_widgets/widgets/ring_progress_bar/ring_progress_bar.py,sha256=sU4Dur2XzBVfDYAYazI6pjOZOhzggoQIuc9VD3PWgac,24073
143
146
  bec_widgets/widgets/scan_control/__init__.py,sha256=IOfHl15vxb_uC6KN62-PeUzbBha_vQyqkkXbJ2HU674,38
144
- bec_widgets/widgets/scan_control/scan_control.py,sha256=u2fjSUiSRYTkIq9WhdfQuQV6Sv3iWWcSfCraVGro1RQ,7686
147
+ bec_widgets/widgets/scan_control/scan_control.py,sha256=lrnT3Oz7XH-zy65qSgVPoCRTAyJmryMZoBhvcY-ZP2M,7697
145
148
  bec_widgets/widgets/scan_control/scan_group_box.py,sha256=8XGpYcdKTEtiqOFbBxZ6xV07ZJ_tg9R-JDfsdTdqXSI,7400
146
149
  bec_widgets/widgets/text_box/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
147
150
  bec_widgets/widgets/text_box/text_box.py,sha256=dg2gpOqdBZNKD08mygb40twweFBiG-xsXz0GlIhfXV0,4240
@@ -216,7 +219,7 @@ tests/unit_tests/test_bec_figure.py,sha256=8AojxszCIzMi6EYB5mVFMQjk4pjgBCSp6PH2J
216
219
  tests/unit_tests/test_bec_image.py,sha256=mjvcrHgOF_FCj6WbUyxvZH9HL63QGA5C0PNZ5dXYn50,2541
217
220
  tests/unit_tests/test_bec_motor_map.py,sha256=dSYopbZS8lGD9cB26Kwmqw5zBoKCZs8t7DEEr50ug-g,8532
218
221
  tests/unit_tests/test_bec_queue.py,sha256=u-uc-iZeGAS8P90o6Cxy5oz_60zHpirGAu04OgQPDXw,4598
219
- tests/unit_tests/test_bec_status_box.py,sha256=xR8c-hXFI9gKpNGhnnC5l_nzazfvPkWkhcAfJ77hxqY,4731
222
+ tests/unit_tests/test_bec_status_box.py,sha256=gZdjyy9DNuUP9UwleTLj2Dp5HUImiqnkHjXWiqL0Q-o,4868
220
223
  tests/unit_tests/test_client_utils.py,sha256=eViJ1Tz-HX9TkMvQH6W8cO-c3_1I8bUc4_Yen6LOc0E,830
221
224
  tests/unit_tests/test_color_validation.py,sha256=xbFbtFDia36XLgaNrX2IwvAX3IDC_Odpj5BGoJSgiIE,2389
222
225
  tests/unit_tests/test_crosshair.py,sha256=3OMAJ2ZaISYXMOtkXf1rPdy94vCr8njeLi6uHblBL9Q,5045
@@ -244,8 +247,8 @@ tests/unit_tests/test_configs/config_device_no_entry.yaml,sha256=hdvue9KLc_kfNzG
244
247
  tests/unit_tests/test_configs/config_scan.yaml,sha256=vo484BbWOjA_e-h6bTjSV9k7QaQHrlAvx-z8wtY-P4E,1915
245
248
  tests/unit_tests/test_msgs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
246
249
  tests/unit_tests/test_msgs/available_scans_message.py,sha256=m_z97hIrjHXXMa2Ex-UvsPmTxOYXfjxyJaGkIY6StTY,46532
247
- bec_widgets-0.79.1.dist-info/METADATA,sha256=C2PR5dChRiBjSv03ME8uiQ3J1i5ub8NbNj6eZ-4fOPM,1427
248
- bec_widgets-0.79.1.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
249
- bec_widgets-0.79.1.dist-info/entry_points.txt,sha256=3otEkCdDB9LZJuBLzG4pFLK5Di0CVybN_12IsZrQ-58,166
250
- bec_widgets-0.79.1.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
251
- bec_widgets-0.79.1.dist-info/RECORD,,
250
+ bec_widgets-0.79.3.dist-info/METADATA,sha256=KNOSryTtLS3GCT2Zw_6V5l9g4xxCSX_MAvinpePvrBU,1427
251
+ bec_widgets-0.79.3.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
252
+ bec_widgets-0.79.3.dist-info/entry_points.txt,sha256=3otEkCdDB9LZJuBLzG4pFLK5Di0CVybN_12IsZrQ-58,166
253
+ bec_widgets-0.79.3.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
254
+ bec_widgets-0.79.3.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.79.1"
7
+ version = "0.79.3"
8
8
  description = "BEC Widgets"
9
9
  requires-python = ">=3.10"
10
10
  classifiers = [
@@ -1,3 +1,4 @@
1
+ # pylint: skip-file
1
2
  from unittest import mock
2
3
 
3
4
  import pytest
@@ -15,19 +16,18 @@ def service_status_fixture():
15
16
 
16
17
  @pytest.fixture
17
18
  def status_box(qtbot, mocked_client, service_status_fixture):
18
- widget = BECStatusBox(
19
- client=mocked_client, service_name="test", bec_service_status_mixin=service_status_fixture
20
- )
19
+ widget = BECStatusBox(client=mocked_client, bec_service_status_mixin=service_status_fixture)
21
20
  qtbot.addWidget(widget)
22
21
  qtbot.waitExposed(widget)
23
22
  yield widget
24
23
 
25
24
 
26
25
  def test_update_top_item(status_box):
27
- assert status_box.children()[0].children()[0].config.status == "IDLE"
26
+ assert status_box.tree.children()[0].children()[0].config.status == "IDLE"
27
+ name = status_box.box_name
28
28
  status_box.update_top_item_status(status="RUNNING")
29
- assert status_box.bec_service_info_container["test"].status == "RUNNING"
30
- assert status_box.children()[0].children()[0].config.status == "RUNNING"
29
+ assert status_box.status_container[name]["info"].status == "RUNNING"
30
+ assert status_box.tree.children()[0].children()[0].config.status == "RUNNING"
31
31
 
32
32
 
33
33
  def test_create_status_widget(status_box):
@@ -48,13 +48,13 @@ def test_bec_service_container(status_box):
48
48
  info = {"test": "test"}
49
49
  metrics = {"metric": "test_metric"}
50
50
  expected_return = BECServiceInfoContainer(
51
- service_name=name, status=status, info=info, metrics=metrics
51
+ service_name=name, status=status.name, info=info, metrics=metrics
52
52
  )
53
- assert status_box.service_name in status_box.bec_service_info_container
54
- assert len(status_box.bec_service_info_container) == 1
55
- status_box._update_bec_service_container(name, status, info, metrics)
56
- assert len(status_box.bec_service_info_container) == 2
57
- assert status_box.bec_service_info_container[name] == expected_return
53
+ assert status_box.box_name in status_box.status_container
54
+ assert len(status_box.status_container) == 1
55
+ status_box._update_status_container(name, status, info, metrics)
56
+ assert len(status_box.status_container) == 2
57
+ assert status_box.status_container[name]["info"] == expected_return
58
58
 
59
59
 
60
60
  def test_add_tree_item(status_box):
@@ -62,10 +62,10 @@ def test_add_tree_item(status_box):
62
62
  status = BECStatus.IDLE
63
63
  info = {"test": "test"}
64
64
  metrics = {"metric": "test_metric"}
65
- assert len(status_box.children()[0].children()) == 1
65
+ assert len(status_box.tree.children()[0].children()) == 1
66
66
  status_box.add_tree_item(name, status, info, metrics)
67
- assert len(status_box.children()[0].children()) == 2
68
- assert name in status_box.tree_items
67
+ assert len(status_box.tree.children()[0].children()) == 2
68
+ assert name in status_box.status_container
69
69
 
70
70
 
71
71
  def test_update_service_status(status_box):
@@ -82,10 +82,10 @@ def test_update_service_status(status_box):
82
82
  services_metrics = {name: ServiceMetricMessage(name=name, metrics=metrics)}
83
83
 
84
84
  with mock.patch.object(status_box, "update_core_services", return_value=services_status):
85
- assert not_connected_name in status_box.tree_items
85
+ assert not_connected_name in status_box.status_container
86
86
  status_box.update_service_status(services_status, services_metrics)
87
- assert status_box.tree_items[name][1].config.metrics == metrics
88
- assert not_connected_name not in status_box.tree_items
87
+ assert status_box.status_container[name]["widget"].config.metrics == metrics
88
+ assert not_connected_name not in status_box.status_container
89
89
 
90
90
 
91
91
  def test_update_core_services(status_box):
@@ -98,15 +98,15 @@ def test_update_core_services(status_box):
98
98
  services_metrics = {name: ServiceMetricMessage(name=name, metrics=metrics)}
99
99
 
100
100
  status_box.update_core_services(services_status, services_metrics)
101
- assert status_box.children()[0].children()[0].config.status == "RUNNING"
102
- assert status_box.tree_items[name][1].config.metrics == metrics
101
+ assert status_box.tree.children()[0].children()[0].config.status == "RUNNING"
102
+ assert status_box.status_container[name]["widget"].config.metrics == metrics
103
103
 
104
104
  status = BECStatus.IDLE
105
105
  services_status = {name: StatusMessage(name=name, status=status, info=info)}
106
106
  services_metrics = {name: ServiceMetricMessage(name=name, metrics=metrics)}
107
107
  status_box.update_core_services(services_status, services_metrics)
108
- assert status_box.children()[0].children()[0].config.status == "ERROR"
109
- assert status_box.tree_items[name][1].config.metrics == metrics
108
+ assert status_box.tree.children()[0].children()[0].config.status == status.name
109
+ assert status_box.status_container[name]["widget"].config.metrics == metrics
110
110
 
111
111
 
112
112
  def test_double_click_item(status_box):
@@ -115,7 +115,9 @@ def test_double_click_item(status_box):
115
115
  info = {"test": "test"}
116
116
  metrics = {"MyData": "This should be shown nicely"}
117
117
  status_box.add_tree_item(name, status, info, metrics)
118
- item, status_item = status_box.tree_items[name]
118
+ container = status_box.status_container[name]
119
+ item = container["item"]
120
+ status_item = container["widget"]
119
121
  with mock.patch.object(status_item, "show_popup") as mock_show_popup:
120
- status_box.itemDoubleClicked.emit(item, 0)
122
+ status_box.tree.itemDoubleClicked.emit(item, 0)
121
123
  assert mock_show_popup.call_count == 1