1
0
mirror of https://github.com/bec-project/bec_widgets.git synced 2025-12-31 19:11:18 +01:00

feat: connect procedure control to logs

This commit is contained in:
2025-11-03 13:49:34 +01:00
parent 3265cb1424
commit d322d3c26c
3 changed files with 89 additions and 9 deletions

View File

@@ -12,6 +12,7 @@ from bec_lib.messages import (
from bec_qthemes._icon.material_icons import material_icon
from bec_server.scan_server.procedures.helper import FrontendProcedureHelper
from pydantic import BaseModel, ConfigDict
from qtpy.QtCore import Signal
from qtpy.QtWidgets import (
QHBoxLayout,
QToolButton,
@@ -107,6 +108,9 @@ class JobItem(_ActionItem):
self._msg = config.msg
self._init_params_display()
def queue(self):
return self._msg.queue
def _init_params_display(self):
self.setText(self._config.params_column, self._short_params_text())
self.setToolTip(self._config.params_column, self._long_params_html())
@@ -178,6 +182,9 @@ class QueueItem(_ActionItem):
_ItemConfig(base=self._config, msg=msg),
)
def queue(self):
return self._queue
@SafeSlot()
def _abort_self(self):
self._config.helper.request.abort_queue(self._queue)
@@ -209,6 +216,8 @@ class CategoryItem(QTreeWidgetItem):
class ProcedureControl(BECWidget, QWidget):
queue_selected = Signal(str)
def __init__(self, parent=None, client=None, config=None, gui_id: str | None = None, **kwargs):
config = config or ConnectionConfig()
super().__init__(parent=parent, client=client, config=config, gui_id=gui_id, **kwargs)
@@ -217,6 +226,17 @@ class ProcedureControl(BECWidget, QWidget):
self._setup_ui()
self.bec_dispatcher.connect_slot(self._update, MessageEndpoints.procedure_queue_notif())
self._init_queues()
self._content.itemSelectionChanged.connect(self.on_selection_changed)
def on_selection_changed(self):
selected_items = self._content.selectedItems()
if len(selected_items) != 1:
self.queue_selected.emit("")
return
if isinstance((item := selected_items[0]), (QueueItem, JobItem)):
self.queue_selected.emit(item.queue())
return
self.queue_selected.emit("")
@SafeSlot(ProcedureQNotifMessage, dict)
def _update(self, msg: dict | ProcedureQNotifMessage, _):
@@ -237,7 +257,6 @@ class ProcedureControl(BECWidget, QWidget):
self._content.setAlternatingRowColors(True)
self._content.setHeaderLabels(["name", "status", "params", "actions"])
self._layout.addWidget(self._content)
self._content.header().resizeSection(0, 250)
config = partial(_BaseConfig, helper=self._helper, tree=self._content, actions_column=3)

View File

@@ -32,15 +32,15 @@ class ProcedureLogs(BECWidget, QWidget):
self._layout.addWidget(self.widget)
@SafeSlot(dict, dict)
def _trigger_update(self, msg, _):
def _update(self, msg, _):
self.widget.append(msg.get("data").strip())
def _update(self):
def _init_content(self):
if self._queue is None:
self.widget.setText("")
return
if msgs := self._conn.xread(MessageEndpoints.procedure_logs(self._queue)):
self.widget.append("".join(msg.get("data").data.strip() for msg in msgs))
if msgs := self._conn.xread(MessageEndpoints.procedure_logs(self._queue), from_start=True):
self.widget.append("\n".join(msg.get("data").data.strip() for msg in msgs))
@SafeSlot(None)
@SafeSlot(str)
@@ -53,16 +53,18 @@ class ProcedureLogs(BECWidget, QWidget):
@queue.setter
def queue(self, queue: str | None) -> None:
if self._queue == queue:
return
if self._queue is not None:
self.bec_dispatcher.disconnect_slot(
self._trigger_update, MessageEndpoints.procedure_logs(self._queue)
self._update, MessageEndpoints.procedure_logs(self._queue)
)
self._queue = queue
self._queue = queue or None
if self._queue is not None:
self.bec_dispatcher.connect_slot(
self._trigger_update, MessageEndpoints.procedure_logs(self._queue)
self._update, MessageEndpoints.procedure_logs(self._queue)
)
self._update()
self._init_content()
if __name__ == "__main__":

View File

@@ -0,0 +1,59 @@
from qtpy.QtWidgets import QVBoxLayout, QWidget
from bec_widgets import BECWidget
from bec_widgets.utils.toolbars.toolbar import ModularToolBar
from bec_widgets.widgets.containers.ads import CDockManager, CDockWidget, DockWidgetArea
from bec_widgets.widgets.containers.advanced_dock_area.advanced_dock_area import AdvancedDockArea
from bec_widgets.widgets.control.procedure_control.procedure_control import ProcedureControl
from bec_widgets.widgets.control.procedure_control.procedure_logs import ProcedureLogs
class ProcedurePanel(BECWidget, QWidget):
def __init__(self, parent=None, **kwargs):
super().__init__(parent=parent, **kwargs)
# Top-level layout hosting a toolbar and the dock manager
self._root_layout = QVBoxLayout(self)
self._root_layout.setContentsMargins(0, 0, 0, 0)
self._root_layout.setSpacing(0)
self.toolbar = ModularToolBar(self)
self._root_layout.addWidget(self.toolbar)
self.dock_manager = CDockManager(self)
self.dock_manager.setStyleSheet("")
self._root_layout.addWidget(self.dock_manager)
self.procedure_control = ProcedureControl(parent=self)
self.procedure_logs = ProcedureLogs(parent=self)
self.procedure_control_dock = CDockWidget("Procedure Control", self)
self.procedure_control_dock.setWidget(self.procedure_control)
self.procedure_logs_dock = CDockWidget("Procedure Logs", self)
self.procedure_logs_dock.setWidget(self.procedure_logs)
self.dock_manager.addDockWidget(
DockWidgetArea.TopDockWidgetArea, self.procedure_control_dock
)
self.dock_manager.addDockWidget(
DockWidgetArea.BottomDockWidgetArea, self.procedure_logs_dock
)
for dock in self.dock_manager.dockWidgets():
dock.setFeature(CDockWidget.DockWidgetFeature.DockWidgetClosable, False)
dock.setFeature(CDockWidget.DockWidgetFeature.DockWidgetFloatable, True)
dock.setFeature(CDockWidget.DockWidgetFeature.DockWidgetMovable, False)
self.procedure_control.queue_selected.connect(self.procedure_logs.set_queue)
if __name__ == "__main__":
import sys
from qtpy.QtWidgets import QApplication
app = QApplication(sys.argv)
widget = ProcedurePanel()
widget.show()
sys.exit(app.exec())