0
0
mirror of https://github.com/bec-project/bec_widgets.git synced 2025-07-14 11:41:49 +02:00

refactor: minor fixes

This commit is contained in:
2025-03-10 16:02:34 +01:00
parent a9b36a4c45
commit 94962fe34f
6 changed files with 70 additions and 51 deletions

View File

@ -1380,27 +1380,10 @@ class BECImageWidget(RPCBase):
class BECMainWindow(RPCBase):
@property
@rpc_call
def _config_dict(self) -> "dict":
def remove(self):
"""
Get the configuration of the widget.
Returns:
dict: The configuration of the widget.
"""
@rpc_call
def _get_all_rpc(self) -> "dict":
"""
Get all registered RPC objects.
"""
@property
@rpc_call
def _rpc_id(self) -> "str":
"""
Get the RPC ID of the widget.
Cleanup the BECConnector
"""

View File

@ -36,6 +36,8 @@ else:
logger = bec_logger.logger
IGNORE_WIDGETS = ["BECDockArea", "BECDock"]
def _filter_output(output: str) -> str:
"""
@ -176,7 +178,7 @@ class AvailableWidgetsNamespace:
def __init__(self):
for widget in client.Widgets:
name = widget.value
if name in ["BECDockArea", "BECDock"]:
if name in IGNORE_WIDGETS:
continue
setattr(self, name, name)
@ -201,17 +203,6 @@ class BECDockArea(client.BECDockArea):
# Add namespaces for DockArea
self.elements = WidgetNameSpace()
def delete(self, dock_name):
# Don't close the bec dock area
if dock_name == "bec":
raise ValueError("Cannot delete the bec dock area")
super().delete(dock_name)
def remove(self):
if self._name == "bec":
raise ValueError("Cannot delete the bec dock area")
super().remove()
class BECGuiClient(RPCBase):
"""BEC GUI client class. Container for GUI applications within Python."""
@ -231,6 +222,7 @@ class BECGuiClient(RPCBase):
self._process_output_processing_thread = None
self._exposed_dock_areas = []
self._registry_state = {}
self._ipython_registry = {}
self.available_widgets = AvailableWidgetsNamespace()
def connect_to_gui_server(self, gui_id: str) -> None:
@ -282,7 +274,7 @@ class BECGuiClient(RPCBase):
logger.error(f"Error loading auto update script from plugin: {str(e)}")
return None
# FIME AUTO UPDATES
# FIXME AUTO UPDATES
# @property
# def selected_device(self) -> str | None:
# """
@ -347,7 +339,7 @@ class BECGuiClient(RPCBase):
self._do_show_all()
self._gui_started_event.set()
def _start_server(self, wait=False) -> None:
def _start_server(self, wait: bool = False) -> None:
"""
Start the GUI server, and execute callback when it is launched
"""
@ -382,16 +374,16 @@ class BECGuiClient(RPCBase):
rpc_client = RPCBase(gui_id=f"{self._gui_id}:window", parent=self)
return rpc_client._run_rpc("_dump")
def _start(self):
def _start(self, wait: bool = False) -> None:
self._killed = False
self._client.connector.register(
MessageEndpoints.gui_registry_state(self._gui_id), cb=self._handle_registry_update
)
return self._start_server()
return self._start_server(wait=wait)
def start(self):
def start(self, wait: bool = False) -> None:
"""Start the GUI server."""
return self._start()
return self._start(wait=wait)
def _handle_registry_update(self, msg: StreamMessage) -> None:
self._registry_state = msg["data"].state
@ -431,24 +423,36 @@ class BECGuiClient(RPCBase):
"""Hide the GUI window."""
return self._hide_all()
def new(self, name: str | None = None, wait: bool = True) -> BECDockArea:
def new(
self,
name: str | None = None,
wait: bool = True,
geometry: tuple[int, int, int, int] | None = None,
) -> BECDockArea:
"""Create a new top-level dock area.
Args:
name(str, optional): The name of the dock area. Defaults to None.
wait(bool, optional): Whether to wait for the server to start. Defaults to True.
geometry(tuple[int, int, int, int] | None): The geometry of the dock area (pos_x, pos_y, w, h)
Returns:
BECDockArea: The new dock area.
"""
if len(self.window_list) == 0:
self.show()
if wait:
with wait_for_server(self):
rpc_client = RPCBase(gui_id=f"{self._gui_id}:window", parent=self)
widget = rpc_client._run_rpc(
"new_dock_area", name
"new_dock_area", name, geometry
) # pylint: disable=protected-access
self._ipython_registry[widget._gui_id] = widget
return widget
rpc_client = RPCBase(gui_id=f"{self._gui_id}:window", parent=self)
widget = rpc_client._run_rpc("new_dock_area", name) # pylint: disable=protected-access
widget = rpc_client._run_rpc(
"new_dock_area", name, geometry
) # pylint: disable=protected-access
self._ipython_registry[widget._gui_id] = widget
return widget
def delete(self, name: str) -> None:
@ -477,8 +481,16 @@ class BECGuiClient(RPCBase):
for dock_area_info in self._registry_state.values():
name = dock_area_info["name"]
gui_id = dock_area_info["gui_id"]
obj = self._ipython_registry.get("gui_id")
if obj is None:
dock_area = BECDockArea(gui_id=gui_id, name=name, parent=self)
self._top_level[name] = dock_area
# weak ref to for all widgets
self._ipython_registry[gui_id] = dock_area
else:
# update namespace
dock_area = obj
dock_area = BECDockArea(gui_id=gui_id, name=name, parent=self)
self._top_level[name] = dock_area
self._exposed_dock_areas.append(name)
setattr(self, name, dock_area)

View File

@ -2,6 +2,7 @@ from __future__ import annotations
from typing import Any
from bec_widgets.cli.client_utils import IGNORE_WIDGETS
from bec_widgets.utils.bec_widget import BECWidget
@ -34,10 +35,7 @@ class RPCWidgetHandler:
clss = get_custom_classes("bec_widgets")
self._widget_classes = {
cls.__name__: cls
for cls in clss.widgets
if cls.__name__
not in ["BECDockArea", "BECDock"] # Exclude these classes due to hierarchy
cls.__name__: cls for cls in clss.widgets if cls.__name__ not in IGNORE_WIDGETS
}
def create_widget(self, widget_type, name: str | None = None, **kwargs) -> BECWidget:

View File

@ -7,6 +7,7 @@ from pydantic import Field
from pyqtgraph.dockarea import Dock, DockLabel
from qtpy import QtCore, QtGui
from bec_widgets.cli.client_utils import IGNORE_WIDGETS
from bec_widgets.cli.rpc.rpc_register import RPCRegister
from bec_widgets.cli.rpc.rpc_widget_handler import widget_handler
from bec_widgets.utils import ConnectionConfig, GridLayoutManager
@ -317,7 +318,7 @@ class BECDock(BECWidget, Dock):
)
# Check that Widget is not BECDock or BECDockArea
widget_class_name = widget if isinstance(widget, str) else widget.__class__.__name__
if widget_class_name in ["BECDock", "BECDockArea"]:
if widget_class_name in IGNORE_WIDGETS:
raise ValueError(f"Widget {widget} can not be added to dock.")
if isinstance(widget, str):

View File

@ -482,6 +482,8 @@ class BECDockArea(BECWidget, QWidget):
if __name__ == "__main__": # pragma: no cover
import sys
from bec_widgets.utils.colors import set_theme
app = QApplication([])
@ -491,5 +493,7 @@ if __name__ == "__main__": # pragma: no cover
# dock_1 = dock_area.new(name="dock_0", widget="Waveform")
dock_area.new(widget="Waveform")
dock_area.show()
dock_area.setGeometry(100, 100, 800, 600)
app.topLevelWidgets()
app.exec_()
sys.exit(app.exec_())

View File

@ -1,14 +1,17 @@
from bec_lib.logger import bec_logger
from qtpy.QtWidgets import QApplication, QMainWindow
from bec_widgets.cli.rpc.rpc_register import RPCRegister
from bec_widgets.utils import BECConnector
from bec_widgets.utils.bec_widget import BECWidget
from bec_widgets.utils.container_utils import WidgetContainerUtils
from bec_widgets.widgets.containers.dock.dock_area import BECDockArea
logger = bec_logger.logger
class BECMainWindow(QMainWindow, BECConnector):
def __init__(self, *args, **kwargs):
BECConnector.__init__(self, **kwargs)
class BECMainWindow(BECWidget, QMainWindow):
def __init__(self, gui_id: str = None, *args, **kwargs):
BECWidget.__init__(self, gui_id=gui_id, **kwargs)
QMainWindow.__init__(self, *args, **kwargs)
def _dump(self):
@ -35,7 +38,17 @@ class BECMainWindow(QMainWindow, BECConnector):
}
return info
def new_dock_area(self, name: str | None = None) -> BECDockArea:
def new_dock_area(
self, name: str | None = None, geometry: tuple[int, int, int, int] | None = None
) -> BECDockArea:
"""Create a new dock area.
Args:
name(str): The name of the dock area.
geometry(tuple): The geometry parameters to be passed to the dock area.
Returns:
BECDockArea: The newly created dock area.
"""
rpc_register = RPCRegister()
existing_dock_areas = rpc_register.get_names_of_rpc_by_class_type(BECDockArea)
if name is not None:
@ -50,5 +63,13 @@ class BECMainWindow(QMainWindow, BECConnector):
dock_area.resize(dock_area.minimumSizeHint())
# TODO Should we simply use the specified name as title here?
dock_area.window().setWindowTitle(f"BEC - {name}")
logger.info(f"Created new dock area: {name}")
logger.info(f"Existing dock areas: {geometry}")
if geometry is not None:
dock_area.setGeometry(*geometry)
dock_area.show()
return dock_area
def cleanup(self):
# TODO
super().close()