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

feat(bec_widget): attach/detach method for all widgets + client regenerated

This commit is contained in:
2025-08-07 16:05:43 +02:00
parent ad85472698
commit 9488923381
16 changed files with 408 additions and 17 deletions

View File

@@ -106,6 +106,18 @@ class AbortButton(RPCBase):
Cleanup the BECConnector
"""
@rpc_call
def attach(self):
"""
None
"""
@rpc_call
def detach(self):
"""
Detach the widget from its parent dock widget (if widget is in the dock), making it a floating widget.
"""
class AutoUpdates(RPCBase):
@property
@@ -442,6 +454,18 @@ class BECMainWindow(RPCBase):
Cleanup the BECConnector
"""
@rpc_call
def attach(self):
"""
None
"""
@rpc_call
def detach(self):
"""
Detach the widget from its parent dock widget (if widget is in the dock), making it a floating widget.
"""
class BECProgressBar(RPCBase):
"""A custom progress bar with smooth transitions. The displayed text can be customized using a template."""
@@ -525,6 +549,18 @@ class BECQueue(RPCBase):
Cleanup the BECConnector
"""
@rpc_call
def attach(self):
"""
None
"""
@rpc_call
def detach(self):
"""
Detach the widget from its parent dock widget (if widget is in the dock), making it a floating widget.
"""
class BECStatusBox(RPCBase):
"""An autonomous widget to display the status of BEC services."""
@@ -541,6 +577,25 @@ class BECStatusBox(RPCBase):
Cleanup the BECConnector
"""
@rpc_call
def attach(self):
"""
None
"""
@rpc_call
def detach(self):
"""
Detach the widget from its parent dock widget (if widget is in the dock), making it a floating widget.
"""
@rpc_timeout(None)
@rpc_call
def screenshot(self, file_name: "str | None" = None):
"""
Take a screenshot of the dock area and save it to a file.
"""
class BaseROI(RPCBase):
"""Base class for all Region of Interest (ROI) implementations."""
@@ -1002,6 +1057,18 @@ class DarkModeButton(RPCBase):
Cleanup the BECConnector
"""
@rpc_call
def attach(self):
"""
None
"""
@rpc_call
def detach(self):
"""
Detach the widget from its parent dock widget (if widget is in the dock), making it a floating widget.
"""
class DeviceBrowser(RPCBase):
"""DeviceBrowser is a widget that displays all available devices in the current BEC session."""
@@ -1012,6 +1079,18 @@ class DeviceBrowser(RPCBase):
Cleanup the BECConnector
"""
@rpc_call
def attach(self):
"""
None
"""
@rpc_call
def detach(self):
"""
Detach the widget from its parent dock widget (if widget is in the dock), making it a floating widget.
"""
class DeviceComboBox(RPCBase):
"""Combobox widget for device input with autocomplete for device names."""
@@ -1045,6 +1124,18 @@ class DeviceInputBase(RPCBase):
Cleanup the BECConnector
"""
@rpc_call
def attach(self):
"""
None
"""
@rpc_call
def detach(self):
"""
Detach the widget from its parent dock widget (if widget is in the dock), making it a floating widget.
"""
class DeviceLineEdit(RPCBase):
"""Line edit widget for device input with autocomplete for device names."""
@@ -1433,6 +1524,18 @@ class Heatmap(RPCBase):
Minimum decimal places for crosshair when dynamic precision is enabled.
"""
@rpc_call
def attach(self):
"""
None
"""
@rpc_call
def detach(self):
"""
Detach the widget from its parent dock widget (if widget is in the dock), making it a floating widget.
"""
@rpc_timeout(None)
@rpc_call
def screenshot(self, file_name: "str | None" = None):
@@ -1978,6 +2081,18 @@ class Image(RPCBase):
Minimum decimal places for crosshair when dynamic precision is enabled.
"""
@rpc_call
def attach(self):
"""
None
"""
@rpc_call
def detach(self):
"""
Detach the widget from its parent dock widget (if widget is in the dock), making it a floating widget.
"""
@rpc_timeout(None)
@rpc_call
def screenshot(self, file_name: "str | None" = None):
@@ -2590,6 +2705,25 @@ class MonacoWidget(RPCBase):
str: The LSP header.
"""
@rpc_call
def attach(self):
"""
None
"""
@rpc_call
def detach(self):
"""
Detach the widget from its parent dock widget (if widget is in the dock), making it a floating widget.
"""
@rpc_timeout(None)
@rpc_call
def screenshot(self, file_name: "str | None" = None):
"""
Take a screenshot of the dock area and save it to a file.
"""
class MotorMap(RPCBase):
"""Motor map widget for plotting motor positions in 2D including a trace of the last points."""
@@ -2865,6 +2999,18 @@ class MotorMap(RPCBase):
The font size of the legend font.
"""
@rpc_call
def attach(self):
"""
None
"""
@rpc_call
def detach(self):
"""
Detach the widget from its parent dock widget (if widget is in the dock), making it a floating widget.
"""
@rpc_timeout(None)
@rpc_call
def screenshot(self, file_name: "str | None" = None):
@@ -3277,6 +3423,18 @@ class MultiWaveform(RPCBase):
Minimum decimal places for crosshair when dynamic precision is enabled.
"""
@rpc_call
def attach(self):
"""
None
"""
@rpc_call
def detach(self):
"""
Detach the widget from its parent dock widget (if widget is in the dock), making it a floating widget.
"""
@rpc_timeout(None)
@rpc_call
def screenshot(self, file_name: "str | None" = None):
@@ -3498,6 +3656,18 @@ class PositionerBox(RPCBase):
positioner (Positioner | str) : Positioner to set, accepts str or the device
"""
@rpc_call
def attach(self):
"""
None
"""
@rpc_call
def detach(self):
"""
Detach the widget from its parent dock widget (if widget is in the dock), making it a floating widget.
"""
@rpc_timeout(None)
@rpc_call
def screenshot(self, file_name: "str | None" = None):
@@ -3527,6 +3697,18 @@ class PositionerBox2D(RPCBase):
positioner (Positioner | str) : Positioner to set, accepts str or the device
"""
@rpc_call
def attach(self):
"""
None
"""
@rpc_call
def detach(self):
"""
Detach the widget from its parent dock widget (if widget is in the dock), making it a floating widget.
"""
@rpc_timeout(None)
@rpc_call
def screenshot(self, file_name: "str | None" = None):
@@ -3547,6 +3729,18 @@ class PositionerControlLine(RPCBase):
positioner (Positioner | str) : Positioner to set, accepts str or the device
"""
@rpc_call
def attach(self):
"""
None
"""
@rpc_call
def detach(self):
"""
Detach the widget from its parent dock widget (if widget is in the dock), making it a floating widget.
"""
@rpc_timeout(None)
@rpc_call
def screenshot(self, file_name: "str | None" = None):
@@ -3566,6 +3760,25 @@ class PositionerGroup(RPCBase):
Device names must be separated by space
"""
@rpc_call
def attach(self):
"""
None
"""
@rpc_call
def detach(self):
"""
Detach the widget from its parent dock widget (if widget is in the dock), making it a floating widget.
"""
@rpc_timeout(None)
@rpc_call
def screenshot(self, file_name: "str | None" = None):
"""
Take a screenshot of the dock area and save it to a file.
"""
class RectangularROI(RPCBase):
"""Defines a rectangular Region of Interest (ROI) with additional functionality."""
@@ -3705,6 +3918,18 @@ class ResetButton(RPCBase):
Cleanup the BECConnector
"""
@rpc_call
def attach(self):
"""
None
"""
@rpc_call
def detach(self):
"""
Detach the widget from its parent dock widget (if widget is in the dock), making it a floating widget.
"""
class ResumeButton(RPCBase):
"""A button that continue scan queue."""
@@ -3715,6 +3940,18 @@ class ResumeButton(RPCBase):
Cleanup the BECConnector
"""
@rpc_call
def attach(self):
"""
None
"""
@rpc_call
def detach(self):
"""
Detach the widget from its parent dock widget (if widget is in the dock), making it a floating widget.
"""
class Ring(RPCBase):
@rpc_call
@@ -3996,6 +4233,25 @@ class RingProgressBar(RPCBase):
bool: True if scan segment updates are enabled.
"""
@rpc_call
def attach(self):
"""
None
"""
@rpc_call
def detach(self):
"""
Detach the widget from its parent dock widget (if widget is in the dock), making it a floating widget.
"""
@rpc_timeout(None)
@rpc_call
def screenshot(self, file_name: "str | None" = None):
"""
Take a screenshot of the dock area and save it to a file.
"""
class SBBMonitor(RPCBase):
"""A widget to display the SBB monitor website."""
@@ -4007,9 +4263,15 @@ class ScanControl(RPCBase):
"""Widget to submit new scans to the queue."""
@rpc_call
def remove(self):
def attach(self):
"""
Cleanup the BECConnector
None
"""
@rpc_call
def detach(self):
"""
Detach the widget from its parent dock widget (if widget is in the dock), making it a floating widget.
"""
@rpc_timeout(None)
@@ -4029,6 +4291,18 @@ class ScanProgressBar(RPCBase):
Cleanup the BECConnector
"""
@rpc_call
def attach(self):
"""
None
"""
@rpc_call
def detach(self):
"""
Detach the widget from its parent dock widget (if widget is in the dock), making it a floating widget.
"""
class ScatterCurve(RPCBase):
"""Scatter curve item for the scatter waveform widget."""
@@ -4327,6 +4601,18 @@ class ScatterWaveform(RPCBase):
Minimum decimal places for crosshair when dynamic precision is enabled.
"""
@rpc_call
def attach(self):
"""
None
"""
@rpc_call
def detach(self):
"""
Detach the widget from its parent dock widget (if widget is in the dock), making it a floating widget.
"""
@rpc_timeout(None)
@rpc_call
def screenshot(self, file_name: "str | None" = None):
@@ -4629,6 +4915,18 @@ class StopButton(RPCBase):
Cleanup the BECConnector
"""
@rpc_call
def attach(self):
"""
None
"""
@rpc_call
def detach(self):
"""
Detach the widget from its parent dock widget (if widget is in the dock), making it a floating widget.
"""
class TextBox(RPCBase):
"""A widget that displays text in plain and HTML format"""
@@ -4661,6 +4959,25 @@ class VSCodeEditor(RPCBase):
class Waveform(RPCBase):
"""Widget for plotting waveforms."""
@rpc_call
def attach(self):
"""
None
"""
@rpc_call
def detach(self):
"""
Detach the widget from its parent dock widget (if widget is in the dock), making it a floating widget.
"""
@rpc_timeout(None)
@rpc_call
def screenshot(self, file_name: "str | None" = None):
"""
Take a screenshot of the dock area and save it to a file.
"""
@property
@rpc_call
def _config_dict(self) -> "dict":
@@ -4965,13 +5282,6 @@ class Waveform(RPCBase):
Minimum decimal places for crosshair when dynamic precision is enabled.
"""
@rpc_timeout(None)
@rpc_call
def screenshot(self, file_name: "str | None" = None):
"""
Take a screenshot of the dock area and save it to a file.
"""
@property
@rpc_call
def curves(self) -> "list[Curve]":
@@ -5213,6 +5523,18 @@ class WebConsole(RPCBase):
Cleanup the BECConnector
"""
@rpc_call
def attach(self):
"""
None
"""
@rpc_call
def detach(self):
"""
Detach the widget from its parent dock widget (if widget is in the dock), making it a floating widget.
"""
class WebsiteWidget(RPCBase):
"""A simple widget to display a website"""
@@ -5252,3 +5574,22 @@ class WebsiteWidget(RPCBase):
"""
Go forward in the history
"""
@rpc_call
def attach(self):
"""
None
"""
@rpc_call
def detach(self):
"""
Detach the widget from its parent dock widget (if widget is in the dock), making it a floating widget.
"""
@rpc_timeout(None)
@rpc_call
def screenshot(self, file_name: "str | None" = None):
"""
Take a screenshot of the dock area and save it to a file.
"""

View File

@@ -4,6 +4,7 @@ from datetime import datetime
from typing import TYPE_CHECKING
import darkdetect
import PySide6QtAds as QtAds
import shiboken6
from bec_lib.logger import bec_logger
from qtpy.QtCore import QObject
@@ -14,6 +15,7 @@ from bec_widgets.utils.bec_connector import BECConnector, ConnectionConfig
from bec_widgets.utils.colors import set_theme
from bec_widgets.utils.error_popups import SafeSlot
from bec_widgets.utils.rpc_decorator import rpc_timeout
from bec_widgets.utils.widget_io import WidgetHierarchy
if TYPE_CHECKING: # pragma: no cover
from bec_widgets.widgets.containers.dock import BECDock
@@ -27,7 +29,7 @@ class BECWidget(BECConnector):
# The icon name is the name of the icon in the icon theme, typically a name taken
# from fonts.google.com/icons. Override this in subclasses to set the icon name.
ICON_NAME = "widgets"
USER_ACCESS = ["remove"]
USER_ACCESS = ["remove", "attach", "detach"]
# pylint: disable=too-many-arguments
def __init__(
@@ -124,6 +126,26 @@ class BECWidget(BECConnector):
screenshot.save(file_name)
logger.info(f"Screenshot saved to {file_name}")
def attach(self):
dock = WidgetHierarchy.find_ancestor(self, QtAds.CDockWidget)
if dock is None:
return
if not dock.isFloating():
return
dock.dockManager().addDockWidget(QtAds.DockWidgetArea.RightDockWidgetArea, dock)
def detach(self):
"""
Detach the widget from its parent dock widget (if widget is in the dock), making it a floating widget.
"""
dock = WidgetHierarchy.find_ancestor(self, QtAds.CDockWidget)
if dock is None:
return
if dock.isFloating():
return
dock.setFloating()
def cleanup(self):
"""Cleanup the widget."""
with RPCRegister.delayed_broadcast():

View File

@@ -33,7 +33,7 @@ class PositionerBox(PositionerBoxBase):
PLUGIN = True
RPC = True
USER_ACCESS = ["set_positioner", "screenshot"]
USER_ACCESS = ["set_positioner", "attach", "detach", "screenshot"]
device_changed = Signal(str, str)
# Signal emitted to inform listeners about a position update
position_update = Signal(float)

View File

@@ -34,7 +34,7 @@ class PositionerBox2D(PositionerBoxBase):
PLUGIN = True
RPC = True
USER_ACCESS = ["set_positioner_hor", "set_positioner_ver", "screenshot"]
USER_ACCESS = ["set_positioner_hor", "set_positioner_ver", "attach", "detach", "screenshot"]
device_changed_hor = Signal(str, str)
device_changed_ver = Signal(str, str)

View File

@@ -62,7 +62,7 @@ class PositionerGroup(BECWidget, QWidget):
PLUGIN = True
ICON_NAME = "grid_view"
USER_ACCESS = ["set_positioners"]
USER_ACCESS = ["set_positioners", "attach", "detach", "screenshot"]
# Signal emitted to inform listeners about a position update of the first positioner
position_update = Signal(float)

View File

@@ -45,7 +45,7 @@ class ScanControl(BECWidget, QWidget):
Widget to submit new scans to the queue.
"""
USER_ACCESS = ["remove", "screenshot"]
USER_ACCESS = ["attach", "detach", "screenshot"]
PLUGIN = True
ICON_NAME = "tune"
ARG_BOX_POSITION: int = 2

View File

@@ -32,6 +32,9 @@ class MonacoWidget(BECWidget, QWidget):
"set_vim_mode_enabled",
"set_lsp_header",
"get_lsp_header",
"attach",
"detach",
"screenshot",
]
def __init__(self, parent=None, config=None, client=None, gui_id=None, **kwargs):

View File

@@ -21,7 +21,16 @@ class WebsiteWidget(BECWidget, QWidget):
PLUGIN = True
ICON_NAME = "travel_explore"
USER_ACCESS = ["set_url", "get_url", "reload", "back", "forward"]
USER_ACCESS = [
"set_url",
"get_url",
"reload",
"back",
"forward",
"attach",
"detach",
"screenshot",
]
def __init__(
self, parent=None, url: str = None, config=None, client=None, gui_id=None, **kwargs

View File

@@ -115,6 +115,8 @@ class Heatmap(ImageBase):
"auto_range_y.setter",
"minimal_crosshair_precision",
"minimal_crosshair_precision.setter",
"attach",
"detach",
"screenshot",
# ImageView Specific Settings
"color_map",

View File

@@ -91,6 +91,8 @@ class Image(ImageBase):
"auto_range_y.setter",
"minimal_crosshair_precision",
"minimal_crosshair_precision.setter",
"attach",
"detach",
"screenshot",
# ImageView Specific Settings
"color_map",

View File

@@ -128,6 +128,8 @@ class MotorMap(PlotBase):
"y_log.setter",
"legend_label_size",
"legend_label_size.setter",
"attach",
"detach",
"screenshot",
# motor_map specific
"color",

View File

@@ -96,6 +96,8 @@ class MultiWaveform(PlotBase):
"legend_label_size.setter",
"minimal_crosshair_precision",
"minimal_crosshair_precision.setter",
"attach",
"detach",
"screenshot",
# MultiWaveform Specific RPC Access
"highlighted_index",

View File

@@ -84,6 +84,8 @@ class ScatterWaveform(PlotBase):
"legend_label_size.setter",
"minimal_crosshair_precision",
"minimal_crosshair_precision.setter",
"attach",
"detach",
"screenshot",
# Scatter Waveform Specific RPC Access
"main_curve",

View File

@@ -63,6 +63,10 @@ class Waveform(PlotBase):
RPC = True
ICON_NAME = "show_chart"
USER_ACCESS = [
# BECWidget Base Class
"attach",
"detach",
"screenshot",
# General PlotBase Settings
"_config_dict",
"enable_toolbar",
@@ -105,7 +109,6 @@ class Waveform(PlotBase):
"legend_label_size.setter",
"minimal_crosshair_precision",
"minimal_crosshair_precision.setter",
"screenshot",
# Waveform Specific RPC Access
"curves",
"x_mode",

View File

@@ -92,6 +92,9 @@ class RingProgressBar(BECWidget, QWidget):
"set_diameter",
"reset_diameter",
"enable_auto_updates",
"attach",
"detach",
"screenshot",
]
def __init__(

View File

@@ -76,7 +76,7 @@ class BECStatusBox(BECWidget, CompactPopupWidget):
PLUGIN = True
CORE_SERVICES = ["DeviceServer", "ScanServer", "SciHub", "ScanBundler", "FileWriterManager"]
USER_ACCESS = ["get_server_state", "remove"]
USER_ACCESS = ["get_server_state", "remove", "attach", "detach", "screenshot"]
service_update = Signal(BECServiceInfoContainer)
bec_core_state = Signal(str)