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:
@ -1380,27 +1380,10 @@ class BECImageWidget(RPCBase):
|
|||||||
|
|
||||||
|
|
||||||
class BECMainWindow(RPCBase):
|
class BECMainWindow(RPCBase):
|
||||||
@property
|
|
||||||
@rpc_call
|
@rpc_call
|
||||||
def _config_dict(self) -> "dict":
|
def remove(self):
|
||||||
"""
|
"""
|
||||||
Get the configuration of the widget.
|
Cleanup the BECConnector
|
||||||
|
|
||||||
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.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,6 +36,8 @@ else:
|
|||||||
|
|
||||||
logger = bec_logger.logger
|
logger = bec_logger.logger
|
||||||
|
|
||||||
|
IGNORE_WIDGETS = ["BECDockArea", "BECDock"]
|
||||||
|
|
||||||
|
|
||||||
def _filter_output(output: str) -> str:
|
def _filter_output(output: str) -> str:
|
||||||
"""
|
"""
|
||||||
@ -176,7 +178,7 @@ class AvailableWidgetsNamespace:
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
for widget in client.Widgets:
|
for widget in client.Widgets:
|
||||||
name = widget.value
|
name = widget.value
|
||||||
if name in ["BECDockArea", "BECDock"]:
|
if name in IGNORE_WIDGETS:
|
||||||
continue
|
continue
|
||||||
setattr(self, name, name)
|
setattr(self, name, name)
|
||||||
|
|
||||||
@ -201,17 +203,6 @@ class BECDockArea(client.BECDockArea):
|
|||||||
# Add namespaces for DockArea
|
# Add namespaces for DockArea
|
||||||
self.elements = WidgetNameSpace()
|
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):
|
class BECGuiClient(RPCBase):
|
||||||
"""BEC GUI client class. Container for GUI applications within Python."""
|
"""BEC GUI client class. Container for GUI applications within Python."""
|
||||||
@ -231,6 +222,7 @@ class BECGuiClient(RPCBase):
|
|||||||
self._process_output_processing_thread = None
|
self._process_output_processing_thread = None
|
||||||
self._exposed_dock_areas = []
|
self._exposed_dock_areas = []
|
||||||
self._registry_state = {}
|
self._registry_state = {}
|
||||||
|
self._ipython_registry = {}
|
||||||
self.available_widgets = AvailableWidgetsNamespace()
|
self.available_widgets = AvailableWidgetsNamespace()
|
||||||
|
|
||||||
def connect_to_gui_server(self, gui_id: str) -> None:
|
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)}")
|
logger.error(f"Error loading auto update script from plugin: {str(e)}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# FIME AUTO UPDATES
|
# FIXME AUTO UPDATES
|
||||||
# @property
|
# @property
|
||||||
# def selected_device(self) -> str | None:
|
# def selected_device(self) -> str | None:
|
||||||
# """
|
# """
|
||||||
@ -347,7 +339,7 @@ class BECGuiClient(RPCBase):
|
|||||||
self._do_show_all()
|
self._do_show_all()
|
||||||
self._gui_started_event.set()
|
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
|
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)
|
rpc_client = RPCBase(gui_id=f"{self._gui_id}:window", parent=self)
|
||||||
return rpc_client._run_rpc("_dump")
|
return rpc_client._run_rpc("_dump")
|
||||||
|
|
||||||
def _start(self):
|
def _start(self, wait: bool = False) -> None:
|
||||||
self._killed = False
|
self._killed = False
|
||||||
self._client.connector.register(
|
self._client.connector.register(
|
||||||
MessageEndpoints.gui_registry_state(self._gui_id), cb=self._handle_registry_update
|
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."""
|
"""Start the GUI server."""
|
||||||
return self._start()
|
return self._start(wait=wait)
|
||||||
|
|
||||||
def _handle_registry_update(self, msg: StreamMessage) -> None:
|
def _handle_registry_update(self, msg: StreamMessage) -> None:
|
||||||
self._registry_state = msg["data"].state
|
self._registry_state = msg["data"].state
|
||||||
@ -431,24 +423,36 @@ class BECGuiClient(RPCBase):
|
|||||||
"""Hide the GUI window."""
|
"""Hide the GUI window."""
|
||||||
return self._hide_all()
|
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.
|
"""Create a new top-level dock area.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
name(str, optional): The name of the dock area. Defaults to None.
|
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.
|
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:
|
Returns:
|
||||||
BECDockArea: The new dock area.
|
BECDockArea: The new dock area.
|
||||||
"""
|
"""
|
||||||
|
if len(self.window_list) == 0:
|
||||||
|
self.show()
|
||||||
if wait:
|
if wait:
|
||||||
with wait_for_server(self):
|
with wait_for_server(self):
|
||||||
rpc_client = RPCBase(gui_id=f"{self._gui_id}:window", parent=self)
|
rpc_client = RPCBase(gui_id=f"{self._gui_id}:window", parent=self)
|
||||||
widget = rpc_client._run_rpc(
|
widget = rpc_client._run_rpc(
|
||||||
"new_dock_area", name
|
"new_dock_area", name, geometry
|
||||||
) # pylint: disable=protected-access
|
) # pylint: disable=protected-access
|
||||||
|
self._ipython_registry[widget._gui_id] = widget
|
||||||
return widget
|
return widget
|
||||||
rpc_client = RPCBase(gui_id=f"{self._gui_id}:window", parent=self)
|
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
|
return widget
|
||||||
|
|
||||||
def delete(self, name: str) -> None:
|
def delete(self, name: str) -> None:
|
||||||
@ -477,8 +481,16 @@ class BECGuiClient(RPCBase):
|
|||||||
for dock_area_info in self._registry_state.values():
|
for dock_area_info in self._registry_state.values():
|
||||||
name = dock_area_info["name"]
|
name = dock_area_info["name"]
|
||||||
gui_id = dock_area_info["gui_id"]
|
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._top_level[name] = dock_area
|
||||||
self._exposed_dock_areas.append(name)
|
self._exposed_dock_areas.append(name)
|
||||||
setattr(self, name, dock_area)
|
setattr(self, name, dock_area)
|
||||||
|
@ -2,6 +2,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
from bec_widgets.cli.client_utils import IGNORE_WIDGETS
|
||||||
from bec_widgets.utils.bec_widget import BECWidget
|
from bec_widgets.utils.bec_widget import BECWidget
|
||||||
|
|
||||||
|
|
||||||
@ -34,10 +35,7 @@ class RPCWidgetHandler:
|
|||||||
|
|
||||||
clss = get_custom_classes("bec_widgets")
|
clss = get_custom_classes("bec_widgets")
|
||||||
self._widget_classes = {
|
self._widget_classes = {
|
||||||
cls.__name__: cls
|
cls.__name__: cls for cls in clss.widgets if cls.__name__ not in IGNORE_WIDGETS
|
||||||
for cls in clss.widgets
|
|
||||||
if cls.__name__
|
|
||||||
not in ["BECDockArea", "BECDock"] # Exclude these classes due to hierarchy
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def create_widget(self, widget_type, name: str | None = None, **kwargs) -> BECWidget:
|
def create_widget(self, widget_type, name: str | None = None, **kwargs) -> BECWidget:
|
||||||
|
@ -7,6 +7,7 @@ from pydantic import Field
|
|||||||
from pyqtgraph.dockarea import Dock, DockLabel
|
from pyqtgraph.dockarea import Dock, DockLabel
|
||||||
from qtpy import QtCore, QtGui
|
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_register import RPCRegister
|
||||||
from bec_widgets.cli.rpc.rpc_widget_handler import widget_handler
|
from bec_widgets.cli.rpc.rpc_widget_handler import widget_handler
|
||||||
from bec_widgets.utils import ConnectionConfig, GridLayoutManager
|
from bec_widgets.utils import ConnectionConfig, GridLayoutManager
|
||||||
@ -317,7 +318,7 @@ class BECDock(BECWidget, Dock):
|
|||||||
)
|
)
|
||||||
# Check that Widget is not BECDock or BECDockArea
|
# Check that Widget is not BECDock or BECDockArea
|
||||||
widget_class_name = widget if isinstance(widget, str) else widget.__class__.__name__
|
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.")
|
raise ValueError(f"Widget {widget} can not be added to dock.")
|
||||||
|
|
||||||
if isinstance(widget, str):
|
if isinstance(widget, str):
|
||||||
|
@ -482,6 +482,8 @@ class BECDockArea(BECWidget, QWidget):
|
|||||||
|
|
||||||
if __name__ == "__main__": # pragma: no cover
|
if __name__ == "__main__": # pragma: no cover
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
from bec_widgets.utils.colors import set_theme
|
from bec_widgets.utils.colors import set_theme
|
||||||
|
|
||||||
app = QApplication([])
|
app = QApplication([])
|
||||||
@ -491,5 +493,7 @@ if __name__ == "__main__": # pragma: no cover
|
|||||||
# dock_1 = dock_area.new(name="dock_0", widget="Waveform")
|
# dock_1 = dock_area.new(name="dock_0", widget="Waveform")
|
||||||
dock_area.new(widget="Waveform")
|
dock_area.new(widget="Waveform")
|
||||||
dock_area.show()
|
dock_area.show()
|
||||||
|
dock_area.setGeometry(100, 100, 800, 600)
|
||||||
app.topLevelWidgets()
|
app.topLevelWidgets()
|
||||||
app.exec_()
|
app.exec_()
|
||||||
|
sys.exit(app.exec_())
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
|
from bec_lib.logger import bec_logger
|
||||||
from qtpy.QtWidgets import QApplication, QMainWindow
|
from qtpy.QtWidgets import QApplication, QMainWindow
|
||||||
|
|
||||||
from bec_widgets.cli.rpc.rpc_register import RPCRegister
|
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.utils.container_utils import WidgetContainerUtils
|
||||||
from bec_widgets.widgets.containers.dock.dock_area import BECDockArea
|
from bec_widgets.widgets.containers.dock.dock_area import BECDockArea
|
||||||
|
|
||||||
|
logger = bec_logger.logger
|
||||||
|
|
||||||
class BECMainWindow(QMainWindow, BECConnector):
|
|
||||||
def __init__(self, *args, **kwargs):
|
class BECMainWindow(BECWidget, QMainWindow):
|
||||||
BECConnector.__init__(self, **kwargs)
|
def __init__(self, gui_id: str = None, *args, **kwargs):
|
||||||
|
BECWidget.__init__(self, gui_id=gui_id, **kwargs)
|
||||||
QMainWindow.__init__(self, *args, **kwargs)
|
QMainWindow.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
def _dump(self):
|
def _dump(self):
|
||||||
@ -35,7 +38,17 @@ class BECMainWindow(QMainWindow, BECConnector):
|
|||||||
}
|
}
|
||||||
return info
|
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()
|
rpc_register = RPCRegister()
|
||||||
existing_dock_areas = rpc_register.get_names_of_rpc_by_class_type(BECDockArea)
|
existing_dock_areas = rpc_register.get_names_of_rpc_by_class_type(BECDockArea)
|
||||||
if name is not None:
|
if name is not None:
|
||||||
@ -50,5 +63,13 @@ class BECMainWindow(QMainWindow, BECConnector):
|
|||||||
dock_area.resize(dock_area.minimumSizeHint())
|
dock_area.resize(dock_area.minimumSizeHint())
|
||||||
# TODO Should we simply use the specified name as title here?
|
# TODO Should we simply use the specified name as title here?
|
||||||
dock_area.window().setWindowTitle(f"BEC - {name}")
|
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()
|
dock_area.show()
|
||||||
return dock_area
|
return dock_area
|
||||||
|
|
||||||
|
def cleanup(self):
|
||||||
|
# TODO
|
||||||
|
super().close()
|
||||||
|
Reference in New Issue
Block a user