diff --git a/bec_widgets/widgets/bec_status_box/bec_status_box.py b/bec_widgets/widgets/bec_status_box/bec_status_box.py index fcd55d8b..17483caf 100644 --- a/bec_widgets/widgets/bec_status_box/bec_status_box.py +++ b/bec_widgets/widgets/bec_status_box/bec_status_box.py @@ -65,7 +65,7 @@ class BECServiceStatusMixin(QObject): Args: client (BECClient): The client object to connect to the BEC server. - ß""" + """ services_update = Signal(dict, dict) @@ -83,7 +83,7 @@ class BECServiceStatusMixin(QObject): self.services_update.emit(self.client._services_info, self.client._services_metric) -class BECStatusBox(BECConnector, QWidget): +class BECStatusBox(BECConnector, QTreeWidget): """A widget to display the status of different BEC services. This widget automatically updates the status of all running BEC services, and displays their status. Information about the individual services is collapsible, and double clicking on @@ -116,34 +116,31 @@ class BECStatusBox(BECConnector, QWidget): if isinstance(config, dict): config = BECStatusBoxConfig(**config) super().__init__(client=client, config=config, gui_id=gui_id) - QWidget.__init__(self, parent=parent) + QTreeWidget.__init__(self, parent=parent) self.service_name = service_name self.config = config self.bec_service_info_container = {} self.tree_items = {} - self.layout = None - self.tree_widget = None self.tree_top_item = None self.bec_service_status = BECServiceStatusMixin(client=self.client) self.init_ui() self.bec_service_status.services_update.connect(self.update_service_status) self.bec_core_state.connect(self.update_top_item_status) + self.itemDoubleClicked.connect(self.on_tree_item_double_clicked) def init_ui(self) -> None: """Initialize the UI for the status box, and add QTreeWidget as the basis for the status box.""" - self.layout = QVBoxLayout() - self.init_tree_widget() + self.init_ui_tree_widget() top_label = self._create_status_widget(self.service_name, status=BECStatus.IDLE) self.tree_top_item = QTreeWidgetItem() self.tree_top_item.setExpanded(True) self.tree_top_item.setDisabled(True) - self.tree_widget.addTopLevelItem(self.tree_top_item) - self.tree_widget.setItemWidget(self.tree_top_item, 0, top_label) + self.addTopLevelItem(self.tree_top_item) + self.setItemWidget(self.tree_top_item, 0, top_label) self.service_update.connect(top_label.update_config) - self.setLayout(self.layout) def _create_status_widget( self, service_name: str, status=BECStatus, info: dict = None, metrics: dict = None @@ -183,7 +180,7 @@ class BECStatusBox(BECConnector, QWidget): status (BECStatus): The state of the core services. """ self.bec_service_info_container[self.service_name].status = status - self.service_update.emit(self.bec_service_info_container[self.service_name].dict()) + self.service_update.emit(self.bec_service_info_container[self.service_name].model_dump()) def _update_bec_service_container( self, service_name: str, status: BECStatus, info: dict, metrics: dict = None @@ -228,7 +225,7 @@ class BECStatusBox(BECConnector, QWidget): self._update_bec_service_container( service_name=service_name, status=msg.status, info=msg.info, metrics=metrics ) - self.service_update.emit(self.bec_service_info_container[service_name].dict()) + self.service_update.emit(self.bec_service_info_container[service_name].model_dump()) continue item_widget = self._create_status_widget( @@ -238,7 +235,7 @@ class BECStatusBox(BECConnector, QWidget): item.setDisabled(True) self.service_update.connect(item_widget.update_config) self.tree_top_item.addChild(item) - self.tree_widget.setItemWidget(item, 0, item_widget) + self.setItemWidget(item, 0, item_widget) self.tree_items.update({service_name: (item, item_widget)}) self.check_redundant_tree_items(checked) @@ -271,7 +268,7 @@ class BECStatusBox(BECConnector, QWidget): ) if service_name in self.tree_items: - self.service_update.emit(self.bec_service_info_container[service_name].dict()) + self.service_update.emit(self.bec_service_info_container[service_name].model_dump()) continue self.add_tree_item(service_name, msg.status, msg.info, metrics) @@ -306,14 +303,13 @@ class BECStatusBox(BECConnector, QWidget): item = QTreeWidgetItem() self.service_update.connect(item_widget.update_config) self.tree_top_item.addChild(item) - self.tree_widget.setItemWidget(item, 0, item_widget) + self.setItemWidget(item, 0, item_widget) self.tree_items.update({service_name: (item, item_widget)}) - def init_tree_widget(self) -> None: + def init_ui_tree_widget(self) -> None: """Initialise the tree widget for the status box.""" - self.tree_widget = QTreeWidget() - self.tree_widget.setHeaderHidden(True) - self.tree_widget.setStyleSheet( + self.setHeaderHidden(True) + self.setStyleSheet( "QTreeWidget::item:!selected " "{ " "border: 1px solid gainsboro; " @@ -322,8 +318,6 @@ class BECStatusBox(BECConnector, QWidget): "}" "QTreeWidget::item:selected {}" ) - self.tree_widget.itemDoubleClicked.connect(self.on_tree_item_double_clicked) - self.layout.addWidget(self.tree_widget) @Slot(QTreeWidgetItem, int) def on_tree_item_double_clicked(self, item: QTreeWidgetItem, column: int) -> None: @@ -337,6 +331,10 @@ class BECStatusBox(BECConnector, QWidget): if tree_item == item: status_widget.show_popup() + def closeEvent(self, event): + super().cleanup() + QTreeWidget().closeEvent(event) + def main(): """Main method to run the BECStatusBox widget.""" diff --git a/docs/developer/widgets/widgets.md b/docs/developer/widgets/widgets.md index 17565096..fc55b494 100644 --- a/docs/developer/widgets/widgets.md +++ b/docs/developer/widgets/widgets.md @@ -8,5 +8,4 @@ maxdepth: 2 hidden: false --- -how_to_develop_a_widget/ ``` \ No newline at end of file diff --git a/docs/user/widgets/bec_status_box.gif b/docs/user/widgets/bec_status_box.gif new file mode 100644 index 00000000..757833aa Binary files /dev/null and b/docs/user/widgets/bec_status_box.gif differ diff --git a/docs/user/widgets/bec_status_box.md b/docs/user/widgets/bec_status_box.md index 087dc37c..d0666bed 100644 --- a/docs/user/widgets/bec_status_box.md +++ b/docs/user/widgets/bec_status_box.md @@ -1,8 +1,8 @@ -(user.widgets.text_box)= -# [BEC Status Box](/api_reference/_autosummary/bec_widgets.cli.client.BECStatusBox) +(user.widgets.bec_status_box)= +# BEC Status Box **Purpose:** -The BECStatusBox Widget is a widget that allows you to monitor the status/health of the all running BEC processes. The widget generates the view automatically and updates the status of the processes in real-time. The top level indicates the overall state of the BEC core services (DeviceServer, ScanServer, SciHub, ScanBundler and FileWriter), but you can also see the status of each individual process by opening the collapsed view. In the collapsed view, you can double click on each process to get a popup window with live updates of the metrics for each process in real-time. +The [BECStatusBox]](/api_reference/_autosummary/bec_widgets.cli.client.BECStatusBox) Widget is a widget that allows you to monitor the status/health of the all running BEC processes. The widget generates the view automatically and updates the status of the processes in real-time. The top level indicates the overall state of the BEC core services (DeviceServer, ScanServer, SciHub, ScanBundler and FileWriter), but you can also see the status of each individual process by opening the collapsed view. In the collapsed view, you can double click on each process to get a popup window with live updates of the metrics for each process in real-time. **Key Features:** diff --git a/docs/user/widgets/buttons.md b/docs/user/widgets/buttons.md index 011ec581..2e0022a8 100644 --- a/docs/user/widgets/buttons.md +++ b/docs/user/widgets/buttons.md @@ -1,5 +1,4 @@ (user.widgets.buttons)= - # Buttons Widgets This section consolidates various custom buttons used within the BEC GUIs, facilitating the integration of these diff --git a/docs/user/widgets/widgets.md b/docs/user/widgets/widgets.md index 2a4d7f31..c35212fd 100644 --- a/docs/user/widgets/widgets.md +++ b/docs/user/widgets/widgets.md @@ -13,6 +13,8 @@ spiral_progress_bar/ website/ buttons/ text_box/ +bec_status_box/ + ``` diff --git a/tests/unit_tests/test_bec_status_box.py b/tests/unit_tests/test_bec_status_box.py index 573eca2a..b45c3800 100644 --- a/tests/unit_tests/test_bec_status_box.py +++ b/tests/unit_tests/test_bec_status_box.py @@ -29,8 +29,8 @@ def test_status_box_init(qtbot, mocked_client): widget = BECStatusBox(parent=None, service_name=name, client=mocked_client) qtbot.addWidget(widget) qtbot.waitExposed(widget) - assert widget.tree_widget.headerItem().DontShowIndicator.value == 1 - assert widget.tree_widget.children()[0].children()[0].config.service_name == name + assert widget.headerItem().DontShowIndicator.value == 1 + assert widget.children()[0].children()[0].config.service_name == name def test_update_top_item(qtbot, mocked_client): @@ -83,9 +83,9 @@ def test_add_tree_item(status_box): status = BECStatus.IDLE info = {"test": "test"} metrics = {"metric": "test_metric"} - assert len(status_box.tree_widget.children()[0].children()) == 1 + assert len(status_box.children()[0].children()) == 1 status_box.add_tree_item(name, status, info, metrics) - assert len(status_box.tree_widget.children()[0].children()) == 2 + assert len(status_box.children()[0].children()) == 2 assert name in status_box.tree_items @@ -148,5 +148,5 @@ def test_double_click_item(status_box): status_box.add_tree_item(name, status, info, metrics) item, status_item = status_box.tree_items[name] with mock.patch.object(status_item, "show_popup") as mock_show_popup: - status_box.tree_widget.itemDoubleClicked.emit(item, 0) + status_box.itemDoubleClicked.emit(item, 0) assert mock_show_popup.call_count == 1