0
0
mirror of https://github.com/bec-project/bec_widgets.git synced 2025-07-14 03:31:50 +02:00

WIP object name linked to name and changed order of inheritance for all widgets

This commit is contained in:
2025-04-04 18:14:51 +02:00
parent d4999d8041
commit 4ae6bdd35d
41 changed files with 81 additions and 75 deletions

View File

@ -20,8 +20,10 @@ MODULE_PATH = os.path.dirname(bec_widgets.__file__)
class LaunchWindow(BECWidget, QMainWindow):
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) # FIRST
BECWidget.__init__(self, gui_id=gui_id, **kwargs) # SECOND
self.setObjectName("LaunchWindow")
self.app = QApplication.instance()

View File

@ -127,7 +127,13 @@ class BECConnector:
else:
if not WidgetContainerUtils.has_name_valid_chars(name):
raise ValueError(f"Name {name} contains invalid characters.")
self._name = name if name else self.__class__.__name__
# TODO Hierarchy can be refreshed upon creation
if isinstance(self, QObject):
if not self.objectName():
self.setObjectName(name if name else self.__class__.__name__)
self._name = self.objectName()
else:
self._name = name if name else self.__class__.__name__
self.rpc_register = RPCRegister()
self.rpc_register.add_rpc(self)

View File

@ -43,8 +43,8 @@ class BECWidget(BECConnector):
>>> class MyWidget(BECWidget, QWidget):
>>> def __init__(self, parent=None, client=None, config=None, gui_id=None):
>>> super().__init__(client=client, config=config, gui_id=gui_id)
>>> QWidget.__init__(self, parent=parent)
>>> BECWidget.__init__(self,client=client, config=config, gui_id=gui_id)
Args:

View File

@ -149,9 +149,10 @@ class CLIServer:
config["parent_id"] = obj.parent_id # add parent_id to config
return {
"gui_id": obj.gui_id,
"name": (
obj._name if hasattr(obj, "_name") else obj.__class__.__name__
), # pylint: disable=protected-access
# "name": (
# obj._name if hasattr(obj, "_name") else obj.__class__.__name__
# ), # pylint: disable=protected-access
"name": obj.objectName() if obj.objectName() else obj.__class__.__name__,
"widget_class": obj.__class__.__name__,
"config": config,
"__rpc__": True,

View File

@ -3,6 +3,7 @@ from __future__ import annotations
from abc import ABC, abstractmethod
from PySide6.QtCore import Qt
from qtpy.QtWidgets import (
QApplication,
QCheckBox,
@ -18,6 +19,7 @@ from qtpy.QtWidgets import (
QWidget,
)
from bec_widgets.utils import BECConnector
from bec_widgets.utils.bec_widget import BECWidget
from bec_widgets.widgets.utility.toggle.toggle import ToggleSwitch
@ -295,13 +297,9 @@ class WidgetHierarchy:
is_bec = isinstance(widget, BECWidget)
print_this = (not only_bec_widgets) or is_bec
# If it is a BECWidget and we're showing the parent, climb the chain to find the nearest BECWidget ancestor
if show_parent and is_bec:
ancestor = WidgetHierarchy._get_becwidget_ancestor(widget)
if ancestor is not None:
parent_info = f" parent={ancestor.__class__.__name__}"
else:
parent_info = " parent=None"
parent_info = f" parent={ancestor.__class__.__name__}" if ancestor else " parent=None"
else:
parent_info = ""
@ -313,21 +311,11 @@ class WidgetHierarchy:
widget_info += value_str
print(prefix + widget_info)
# Always recurse so we can discover deeper BECWidgets even if the current widget is not a BECWidget
children = widget.children()
for i, child in enumerate(children):
# Possibly skip known internal child widgets of a QComboBox
if (
exclude_internal_widgets
and isinstance(widget, QComboBox)
and child.__class__.__name__ in ["QFrame", "QBoxLayout", "QListView"]
):
continue
child_prefix = prefix + " "
# Explicitly include all children widgets
children = widget.findChildren(QWidget, options=Qt.FindDirectChildrenOnly)
for child in children:
arrow = "├─ " if child != children[-1] else "└─ "
# Regardless of whether child is BECWidget or not, keep recursing, or we might miss deeper BECWidgets
child_prefix = prefix + " "
WidgetHierarchy.print_widget_hierarchy(
child,
indent + 1,
@ -346,7 +334,7 @@ class WidgetHierarchy:
"""
parent = widget.parent()
while parent is not None:
if isinstance(parent, BECWidget):
if isinstance(parent, BECConnector):
return parent
parent = parent.parent()
return None

View File

@ -148,11 +148,11 @@ class BECDock(BECWidget, Dock):
if isinstance(config, dict):
config = DockConfig(**config)
self.config = config
super().__init__(
client=client, config=config, gui_id=gui_id, name=name, parent_id=parent_id
) # Name was checked and created in BEC Widget
label = CustomDockLabel(text=name, closable=closable)
Dock.__init__(self, name=name, label=label, parent=self, **kwargs)
BECWidget.__init__(
self, client=client, config=config, gui_id=gui_id, name=name, parent_id=parent_id
) # Name was checked and created in BEC Widget
# Dock.__init__(self, name=name, **kwargs)
self.parent_dock_area = parent_dock_area

View File

@ -82,8 +82,9 @@ class BECDockArea(BECWidget, QWidget):
if isinstance(config, dict):
config = DockAreaConfig(**config)
self.config = config
super().__init__(client=client, config=config, gui_id=gui_id, name=name, **kwargs)
QWidget.__init__(self, parent=parent)
BECWidget.__init__(self, client=client, config=config, gui_id=gui_id, name=name, **kwargs)
self.setObjectName("bec")
self._parent = parent
self.layout = QVBoxLayout(self)
self.layout.setSpacing(5)

View File

@ -21,8 +21,8 @@ logger = bec_logger.logger
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)
BECWidget.__init__(self, gui_id=gui_id, **kwargs)
self.app = QApplication.instance()

View File

@ -23,8 +23,8 @@ class AbortButton(BECWidget, QWidget):
scan_id=None,
**kwargs,
):
super().__init__(client=client, config=config, gui_id=gui_id, **kwargs)
QWidget.__init__(self, parent=parent)
BECWidget.__init__(self, client=client, config=config, gui_id=gui_id, **kwargs)
self.get_bec_shortcuts()

View File

@ -14,8 +14,8 @@ class ResetButton(BECWidget, QWidget):
ICON_NAME = "restart_alt"
def __init__(self, parent=None, client=None, config=None, gui_id=None, toolbar=False, **kwargs):
super().__init__(client=client, config=config, gui_id=gui_id, **kwargs)
QWidget.__init__(self, parent=parent)
BECWidget.__init__(self, client=client, config=config, gui_id=gui_id, **kwargs)
self.get_bec_shortcuts()

View File

@ -14,8 +14,8 @@ class ResumeButton(BECWidget, QWidget):
ICON_NAME = "resume"
def __init__(self, parent=None, client=None, config=None, gui_id=None, toolbar=False, **kwargs):
super().__init__(client=client, config=config, gui_id=gui_id, **kwargs)
QWidget.__init__(self, parent=parent)
BECWidget.__init__(self, client=client, config=config, gui_id=gui_id, **kwargs)
self.get_bec_shortcuts()

View File

@ -14,8 +14,8 @@ class StopButton(BECWidget, QWidget):
ICON_NAME = "dangerous"
def __init__(self, parent=None, client=None, config=None, gui_id=None, toolbar=False, **kwargs):
super().__init__(client=client, config=config, gui_id=gui_id, **kwargs)
QWidget.__init__(self, parent=parent)
BECWidget.__init__(self, client=client, config=config, gui_id=gui_id, **kwargs)
self.get_bec_shortcuts()

View File

@ -13,8 +13,8 @@ class PositionIndicator(BECWidget, QWidget):
ICON_NAME = "horizontal_distribute"
def __init__(self, parent=None, client=None, config=None, gui_id=None, **kwargs):
super().__init__(client=client, config=config, gui_id=gui_id, **kwargs)
QWidget.__init__(self, parent=parent)
BECWidget.__init__(self, client=client, config=config, gui_id=gui_id, **kwargs)
self.position = 50
self.min_value = 0
self.max_value = 100

View File

@ -55,8 +55,8 @@ class PositionerBoxBase(BECWidget, CompactPopupWidget):
parent: The parent widget.
device (Positioner): The device to control.
"""
super().__init__(**kwargs)
CompactPopupWidget.__init__(self, parent=parent, layout=QVBoxLayout)
BECWidget.__init__(self, **kwargs)
self._dialog = None
self.get_bec_shortcuts()

View File

@ -69,8 +69,8 @@ class PositionerGroup(BECWidget, QWidget):
Args:
parent: The parent widget.
"""
super().__init__(**kwargs)
QWidget.__init__(self, parent)
BECWidget.__init__(self, **kwargs)
self.get_bec_shortcuts()

View File

@ -47,8 +47,8 @@ class DeviceComboBox(DeviceInputBase, QComboBox):
arg_name: str | None = None,
**kwargs,
):
super().__init__(client=client, config=config, gui_id=gui_id, **kwargs)
QComboBox.__init__(self, parent=parent)
DeviceInputBase.__init__(self, client=client, config=config, gui_id=gui_id, **kwargs)
if arg_name is not None:
self.config.arg_name = arg_name
self.arg_name = arg_name

View File

@ -53,8 +53,8 @@ class DeviceLineEdit(DeviceInputBase, QLineEdit):
self._callback_id = None
self._is_valid_input = False
self._accent_colors = get_accent_colors()
super().__init__(client=client, config=config, gui_id=gui_id, **kwargs)
QLineEdit.__init__(self, parent=parent)
DeviceInputBase.__init__(self, client=client, config=config, gui_id=gui_id, **kwargs)
self.completer = QCompleter(self)
self.setCompleter(self.completer)

View File

@ -40,8 +40,8 @@ class SignalComboBox(DeviceSignalInputBase, QComboBox):
arg_name: str | None = None,
**kwargs,
):
super().__init__(client=client, config=config, gui_id=gui_id, **kwargs)
QComboBox.__init__(self, parent=parent)
DeviceSignalInputBase.__init__(self, client=client, config=config, gui_id=gui_id, **kwargs)
if arg_name is not None:
self.config.arg_name = arg_name
self.arg_name = arg_name

View File

@ -42,8 +42,8 @@ class SignalLineEdit(DeviceSignalInputBase, QLineEdit):
**kwargs,
):
self._is_valid_input = False
super().__init__(client=client, config=config, gui_id=gui_id, **kwargs)
QLineEdit.__init__(self, parent=parent)
DeviceSignalInputBase.__init__(self, client=client, config=config, gui_id=gui_id, **kwargs)
self._accent_colors = get_accent_colors()
self.completer = QCompleter(self)
self.setCompleter(self.completer)

View File

@ -65,8 +65,8 @@ class ScanControl(BECWidget, QWidget):
config = ScanControlConfig(
widget_class=self.__class__.__name__, allowed_scans=allowed_scans
)
super().__init__(client=client, gui_id=gui_id, config=config, **kwargs)
QWidget.__init__(self, parent=parent)
BECWidget.__init__(self, client=client, config=config, gui_id=gui_id, **kwargs)
self._hide_add_remove_buttons = False

View File

@ -44,8 +44,8 @@ class DapComboBox(BECWidget, QWidget):
default_fit: str | None = None,
**kwargs,
):
super().__init__(client=client, gui_id=gui_id, **kwargs)
QWidget.__init__(self, parent=parent)
BECWidget.__init__(self, client=client, config=config, gui_id=gui_id, **kwargs)
self.layout = QVBoxLayout(self)
self.fit_model_combobox = QComboBox(self)
self.layout.addWidget(self.fit_model_combobox)

View File

@ -43,10 +43,10 @@ class LMFitDialog(BECWidget, QWidget):
gui_id (str): GUI ID.
ui_file (str): The UI file to be loaded.
"""
super().__init__(client=client, config=config, gui_id=gui_id, **kwargs)
QWidget.__init__(self, parent=parent)
BECWidget.__init__(self, client=client, config=config, gui_id=gui_id, **kwargs)
self.setProperty("skip_settings", True)
self.setObjectName("LMFitDialog")
# self.setObjectName("LMFitDialog")
self._ui_file = ui_file
self.target_widget = target_widget

View File

@ -51,8 +51,8 @@ class ScanMetadata(BECWidget, QWidget):
initial_extras: list[list[str]] | None = None,
**kwargs,
):
super().__init__(client=client, **kwargs)
QWidget.__init__(self, parent=parent)
BECWidget.__init__(client=client, **kwargs)
self.set_schema(scan_name)

View File

@ -49,8 +49,9 @@ class TextBox(BECWidget, QWidget):
if isinstance(config, dict):
config = TextBoxConfig(**config)
self.config = config
super().__init__(client=client, config=config, gui_id=gui_id, **kwargs)
QWidget.__init__(self, parent)
BECWidget.__init__(self, client=client, config=config, gui_id=gui_id, **kwargs)
self.layout = QVBoxLayout(self)
self.text_box_text_edit = QTextEdit(parent=self)
self.layout.addWidget(self.text_box_text_edit)

View File

@ -26,8 +26,8 @@ class WebsiteWidget(BECWidget, QWidget):
def __init__(
self, parent=None, url: str = None, config=None, client=None, gui_id=None, **kwargs
):
super().__init__(client=client, config=config, gui_id=gui_id, **kwargs)
QWidget.__init__(self, parent=parent)
BECWidget.__init__(self, client=client, config=config, gui_id=gui_id, **kwargs)
layout = QVBoxLayout()
layout.setContentsMargins(0, 0, 0, 0)
self.website = QWebEngineView()

View File

@ -146,8 +146,8 @@ class Minesweeper(BECWidget, QWidget):
USER_ACCESS = []
def __init__(self, parent=None, *args, **kwargs):
super().__init__(*args, **kwargs)
QWidget.__init__(self, parent=parent)
BECWidget.__init__(self, *args, **kwargs)
self._ui_initialised = False
self._timer_start_num_seconds = 0

View File

@ -72,6 +72,7 @@ class ImageItem(BECConnector, pg.ImageItem):
def __init__(
self,
parent=None,
config: Optional[ImageItemConfig] = None,
gui_id: Optional[str] = None,
parent_image=None,
@ -82,8 +83,8 @@ class ImageItem(BECConnector, pg.ImageItem):
self.config = config
else:
self.config = config
super().__init__(config=config, gui_id=gui_id)
pg.ImageItem.__init__(self)
pg.ImageItem.__init__(self, parent=parent)
BECConnector.__init__(self, config=config, gui_id=gui_id)
self.parent_image = parent_image

View File

@ -74,11 +74,10 @@ class PlotBase(BECWidget, QWidget):
) -> None:
if config is None:
config = ConnectionConfig(widget_class=self.__class__.__name__)
super().__init__(client=client, gui_id=gui_id, config=config, **kwargs)
QWidget.__init__(self, parent=parent)
BECWidget.__init__(self, client=client, gui_id=gui_id, config=config, **kwargs)
# For PropertyManager identification
self.setObjectName("PlotBase")
self.get_bec_shortcuts()
# Layout Management

View File

@ -77,9 +77,8 @@ class ScatterCurve(BECConnector, pg.PlotDataItem):
else:
self.config = config
name = config.label
super().__init__(config=config, gui_id=gui_id)
pg.PlotDataItem.__init__(self, name=name)
pg.PlotDataItem.__init__(self, **kwargs, name=name)
BECConnector.__init__(self, config=config, gui_id=gui_id)
self.parent_item = parent_item
self.data_z = None # color scaling needs to be cashed for changing colormap
self.apply_config()

View File

@ -110,9 +110,9 @@ class ScatterWaveform(PlotBase):
super().__init__(
parent=parent, config=config, client=client, gui_id=gui_id, popups=popups, **kwargs
)
self._main_curve = ScatterCurve(parent_item=self)
self._main_curve = ScatterCurve(parent=self, parent_item=self)
# self._main_curve = ScatterCurve(parent_item=self)
# For PropertyManager identification
self.setObjectName("ScatterWaveform")
# Specific GUI elements
self.scatter_dialog = None

View File

@ -79,6 +79,7 @@ class Curve(BECConnector, pg.PlotDataItem):
def __init__(
self,
parent=None,
name: str | None = None,
config: CurveConfig | None = None,
gui_id: str | None = None,
@ -90,9 +91,9 @@ class Curve(BECConnector, pg.PlotDataItem):
self.config = config
else:
self.config = config
super().__init__(config=config, gui_id=gui_id)
pg.PlotDataItem.__init__(self, name=name)
pg.PlotDataItem.__init__(self, parent=parent, name=name)
BECConnector.__init__(self, config=config, gui_id=gui_id)
self.parent_id = parent_item.config.gui_id
self.parent_item = parent_item
self.apply_config()
self.dap_params = None

View File

@ -337,8 +337,8 @@ class CurveTree(BECWidget, QWidget):
) -> None:
if config is None:
config = ConnectionConfig(widget_class=self.__class__.__name__)
super().__init__(client=client, gui_id=gui_id, config=config)
QWidget.__init__(self, parent=parent)
BECWidget.__init__(self, client=client, gui_id=gui_id, config=config)
self.waveform = waveform
if self.waveform and hasattr(self.waveform, "color_palette"):

View File

@ -121,16 +121,23 @@ class Waveform(PlotBase):
client=None,
gui_id: str | None = None,
popups: bool = True,
name=None,
**kwargs,
):
if config is None:
config = WaveformConfig(widget_class=self.__class__.__name__)
super().__init__(
parent=parent, config=config, client=client, gui_id=gui_id, popups=popups, **kwargs
parent=parent,
config=config,
client=client,
gui_id=gui_id,
popups=popups,
name=name,
**kwargs,
)
# For PropertyManager identification
self.setObjectName("Waveform")
# self.setObjectName("Waveform")
# Curve data
self._sync_curves = []
@ -758,7 +765,7 @@ class Waveform(PlotBase):
Returns:
Curve: The newly created curve object, added to the plot.
"""
curve = Curve(config=config, name=name, parent_item=self)
curve = Curve(parent=self, config=config, name=name, parent_item=self)
self.plot_item.addItem(curve)
self._categorise_device_curves()
return curve

View File

@ -25,8 +25,8 @@ class BECProgressBar(BECWidget, QWidget):
ICON_NAME = "page_control"
def __init__(self, parent=None, client=None, config=None, gui_id=None, **kwargs):
super().__init__(client=client, config=config, gui_id=gui_id, **kwargs)
QWidget.__init__(self, parent=parent)
BECWidget.__init__(client=client, config=config, gui_id=gui_id, **kwargs)
accent_colors = get_accent_colors()

View File

@ -110,8 +110,8 @@ class RingProgressBar(BECWidget, QWidget):
if isinstance(config, dict):
config = RingProgressBarConfig(**config, widget_class=self.__class__.__name__)
self.config = config
super().__init__(client=client, config=config, gui_id=gui_id, **kwargs)
QWidget.__init__(self, parent=parent)
BECWidget.__init__(self, client=client, config=config, gui_id=gui_id, **kwargs)
self.get_bec_shortcuts()
self.entry_validator = EntryValidator(self.dev)

View File

@ -44,8 +44,8 @@ class BECQueue(BECWidget, CompactPopupWidget):
refresh_upon_start: bool = True,
**kwargs,
):
super().__init__(client=client, config=config, gui_id=gui_id, **kwargs)
CompactPopupWidget.__init__(self, parent=parent, layout=QVBoxLayout)
BECWidget.__init__(self, client=client, config=config, gui_id=gui_id, **kwargs)
self.layout.setSpacing(0)
self.layout.setContentsMargins(0, 0, 0, 0)

View File

@ -89,8 +89,8 @@ class BECStatusBox(BECWidget, CompactPopupWidget):
gui_id: str = None,
**kwargs,
):
super().__init__(client=client, gui_id=gui_id, **kwargs)
CompactPopupWidget.__init__(self, parent=parent, layout=QHBoxLayout)
BECWidget.__init__(self, client=client, gui_id=gui_id, **kwargs)
self.box_name = box_name
self.status_container = defaultdict(lambda: {"info": None, "item": None, "widget": None})

View File

@ -25,8 +25,8 @@ class DeviceBrowser(BECWidget, QWidget):
gui_id: Optional[str] = None,
**kwargs,
) -> None:
super().__init__(client=client, config=config, gui_id=gui_id, **kwargs)
QWidget.__init__(self, parent)
BECWidget.__init__(self, client=client, config=config, gui_id=gui_id, **kwargs)
self.get_bec_shortcuts()
self.ui = None

View File

@ -30,8 +30,8 @@ class BECSpinBox(BECWidget, QDoubleSpinBox):
) -> None:
if config is None:
config = ConnectionConfig(widget_class=self.__class__.__name__)
super().__init__(client=client, gui_id=gui_id, config=config, **kwargs)
QDoubleSpinBox.__init__(self, parent=parent)
BECWidget.__init__(self, client=client, gui_id=gui_id, config=config, **kwargs)
self.setObjectName("BECSpinBox")
# Make the widget as compact as possible horizontally.

View File

@ -14,8 +14,8 @@ class BECColorMapWidget(BECWidget, QWidget):
RPC = False
def __init__(self, parent=None, cmap: str = "magma", **kwargs):
super().__init__(**kwargs)
QWidget.__init__(self, parent=parent)
BECWidget.__init__(self, **kwargs)
# Create the ColorMapButton
self.button = ColorMapButton()

View File

@ -23,8 +23,8 @@ class DarkModeButton(BECWidget, QWidget):
toolbar: bool = False,
**kwargs,
) -> None:
super().__init__(client=client, gui_id=gui_id, theme_update=True, **kwargs)
QWidget.__init__(self, parent)
BECWidget.__init__(self, client=client, gui_id=gui_id, theme_update=True, **kwargs)
self._dark_mode_enabled = False
self.layout = QHBoxLayout(self)