From 17e525689c553436b31da460d6a75cb452d5538c Mon Sep 17 00:00:00 2001 From: Holler Mirko Date: Wed, 23 Apr 2025 12:59:18 +0200 Subject: [PATCH] initial version of omny alignment gui --- csaxs_bec/bec_widgets/widgets/__init__.py | 0 csaxs_bec/bec_widgets/widgets/client.py | 75 ++++++++++ .../widgets/omny_alignment/__init__.py | 0 .../widgets/omny_alignment/omny_alignment.py | 139 ++++++++++++++++++ .../omny_alignment/omny_alignment.pyproject | 1 + .../widgets/omny_alignment/omny_alignment.ui | 125 ++++++++++++++++ .../omny_alignment/omny_alignment_plugin.py | 54 +++++++ .../omny_alignment/register_omny_alignment.py | 15 ++ csaxs_bec/devices/ids_cameras/ids_camera.py | 2 +- pyproject.toml | 4 +- 10 files changed, 412 insertions(+), 3 deletions(-) create mode 100644 csaxs_bec/bec_widgets/widgets/__init__.py create mode 100644 csaxs_bec/bec_widgets/widgets/client.py create mode 100644 csaxs_bec/bec_widgets/widgets/omny_alignment/__init__.py create mode 100644 csaxs_bec/bec_widgets/widgets/omny_alignment/omny_alignment.py create mode 100644 csaxs_bec/bec_widgets/widgets/omny_alignment/omny_alignment.pyproject create mode 100644 csaxs_bec/bec_widgets/widgets/omny_alignment/omny_alignment.ui create mode 100644 csaxs_bec/bec_widgets/widgets/omny_alignment/omny_alignment_plugin.py create mode 100644 csaxs_bec/bec_widgets/widgets/omny_alignment/register_omny_alignment.py diff --git a/csaxs_bec/bec_widgets/widgets/__init__.py b/csaxs_bec/bec_widgets/widgets/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/csaxs_bec/bec_widgets/widgets/client.py b/csaxs_bec/bec_widgets/widgets/client.py new file mode 100644 index 0000000..0c7f321 --- /dev/null +++ b/csaxs_bec/bec_widgets/widgets/client.py @@ -0,0 +1,75 @@ +# This file was automatically generated by generate_cli.py +# type: ignore + +from __future__ import annotations + +from bec_lib.logger import bec_logger + +from bec_widgets.cli.rpc.rpc_base import RPCBase, rpc_call + +logger = bec_logger.logger + +# pylint: skip-file + + +_Widgets = { + "OmnyAlignment": "OmnyAlignment", +} + + +class OmnyAlignment(RPCBase): + @property + @rpc_call + def enable_live_view(self): + """ + None + """ + + @enable_live_view.setter + @rpc_call + def enable_live_view(self): + """ + None + """ + + @property + @rpc_call + def user_message(self): + """ + None + """ + + @user_message.setter + @rpc_call + def user_message(self): + """ + None + """ + + @property + @rpc_call + def sample_name(self): + """ + None + """ + + @sample_name.setter + @rpc_call + def sample_name(self): + """ + None + """ + + @property + @rpc_call + def enable_move_buttons(self): + """ + None + """ + + @enable_move_buttons.setter + @rpc_call + def enable_move_buttons(self): + """ + None + """ diff --git a/csaxs_bec/bec_widgets/widgets/omny_alignment/__init__.py b/csaxs_bec/bec_widgets/widgets/omny_alignment/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/csaxs_bec/bec_widgets/widgets/omny_alignment/omny_alignment.py b/csaxs_bec/bec_widgets/widgets/omny_alignment/omny_alignment.py new file mode 100644 index 0000000..089101f --- /dev/null +++ b/csaxs_bec/bec_widgets/widgets/omny_alignment/omny_alignment.py @@ -0,0 +1,139 @@ + + +from typing import TypedDict +from bec_widgets.utils.error_popups import SafeSlot +import os +from bec_widgets.utils.bec_widget import BECWidget +from bec_widgets.utils.ui_loader import UILoader +from qtpy.QtWidgets import QWidget, QPushButton, QLineEdit, QLabel, QVBoxLayout +from bec_qthemes import material_icon +from bec_lib.logger import bec_logger + +logger = bec_logger.logger + + +# class OmnyAlignmentUIComponents(TypedDict): +# moveRightButton: QPushButton +# moveLeftButton: QPushButton +# moveUpButton: QPushButton +# moveDownButton: QPushButton +# image: Image + + +class OmnyAlignment(BECWidget, QWidget): + USER_ACCESS = ["enable_live_view", "enable_live_view.setter", "user_message", "user_message.setter","sample_name", "sample_name.setter", "enable_move_buttons", "enable_move_buttons.setter"] + PLUGIN = True + ui_file = "./omny_alignment.ui" + + def __init__(self, parent=None, **kwargs): + super().__init__(parent=parent, **kwargs) + + self._load_ui() + + def _load_ui(self): + current_path = os.path.dirname(__file__) + self.ui = UILoader(self).loader(os.path.join(current_path, self.ui_file)) + layout = QVBoxLayout() + layout.addWidget(self.ui) + self.setLayout(layout) + + icon_options = {"size": (16, 16), "convert_to_pixmap": False} + self.ui.moveRightButton.setText("") + self.ui.moveRightButton.setIcon( + material_icon(icon_name="keyboard_arrow_right", **icon_options) + ) + + self.ui.moveLeftButton.setText("") + self.ui.moveLeftButton.setIcon( + material_icon(icon_name="keyboard_arrow_left", **icon_options) + ) + + self.ui.moveUpButton.setText("") + self.ui.moveUpButton.setIcon( + material_icon(icon_name="keyboard_arrow_up", **icon_options) + ) + + self.ui.moveDownButton.setText("") + self.ui.moveDownButton.setIcon( + material_icon(icon_name="keyboard_arrow_down", **icon_options) + ) + + self.ui.confirmButton.setText("OK") + + + self.ui.liveViewSwitch.enabled.connect(self.on_live_view_enabled) + + + @property + def enable_live_view(self): + return self.ui.liveViewSwitch.checked + + @enable_live_view.setter + def enable_live_view(self, enable:bool): + self.ui.liveViewSwitch.checked = enable + + + @property + def user_message(self): + return self.ui.messageLineEdit.text() + + @user_message.setter + def user_message(self, message:str): + self.ui.messageLineEdit.setText(message) + + @property + def sample_name(self): + return self.ui.sampleLineEdit.text() + + @sample_name.setter + def sample_name(self, message:str): + self.ui.sampleLineEdit.setText(message) + + + @SafeSlot(bool) + def on_live_view_enabled(self, enabled:bool): + from bec_widgets.widgets.plots.image.image import Image + logger.info(f"Live view is enabled: {enabled}") + image: Image = self.ui.image + if enabled: + image.image("cam200") + return + + image.disconnect_monitor("cam200") + + + + @property + def enable_move_buttons(self): + move_up:QPushButton = self.ui.moveUpButton + move_down:QPushButton = self.ui.moveDownButton + move_left:QPushButton = self.ui.moveLeftButton + move_right:QPushButton = self.ui.moveRightButton + return move_up.isEnabled() and move_down.isEnabled() and move_left.isEnabled() and move_right.isEnabled() + + @enable_move_buttons.setter + def enable_move_buttons(self, enabled:bool): + move_up:QPushButton = self.ui.moveUpButton + move_down:QPushButton = self.ui.moveDownButton + move_left:QPushButton = self.ui.moveLeftButton + move_right:QPushButton = self.ui.moveRightButton + + move_up.setEnabled(enabled) + move_down.setEnabled(enabled) + move_left.setEnabled(enabled) + move_right.setEnabled(enabled) + + + + + + +if __name__ == "__main__": + from qtpy.QtWidgets import QApplication + import sys + + app = QApplication(sys.argv) + widget = OmnyAlignment() + + widget.show() + sys.exit(app.exec_()) \ No newline at end of file diff --git a/csaxs_bec/bec_widgets/widgets/omny_alignment/omny_alignment.pyproject b/csaxs_bec/bec_widgets/widgets/omny_alignment/omny_alignment.pyproject new file mode 100644 index 0000000..3182247 --- /dev/null +++ b/csaxs_bec/bec_widgets/widgets/omny_alignment/omny_alignment.pyproject @@ -0,0 +1 @@ +{'files': ['omny_alignment.py']} \ No newline at end of file diff --git a/csaxs_bec/bec_widgets/widgets/omny_alignment/omny_alignment.ui b/csaxs_bec/bec_widgets/widgets/omny_alignment/omny_alignment.ui new file mode 100644 index 0000000..0cd20ea --- /dev/null +++ b/csaxs_bec/bec_widgets/widgets/omny_alignment/omny_alignment.ui @@ -0,0 +1,125 @@ + + + Form + + + + 0 + 0 + 988 + 821 + + + + Form + + + + + + + + PushButton + + + + + + + PushButton + + + + + + + Up + + + + + + + PushButton + + + + + + + PushButton + + + + + + + + + + + + + + + + + Sample + + + + + + + Message + + + + + + + + + false + + + false + + + cam200 + + + 3 + + + + + + + + + + Live View + + + Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter + + + + + + + + Image + QWidget +
image
+
+ + ToggleSwitch + QWidget +
toggle_switch
+
+
+ + +
diff --git a/csaxs_bec/bec_widgets/widgets/omny_alignment/omny_alignment_plugin.py b/csaxs_bec/bec_widgets/widgets/omny_alignment/omny_alignment_plugin.py new file mode 100644 index 0000000..cbbd81b --- /dev/null +++ b/csaxs_bec/bec_widgets/widgets/omny_alignment/omny_alignment_plugin.py @@ -0,0 +1,54 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +from qtpy.QtDesigner import QDesignerCustomWidgetInterface + +from bec_widgets.utils.bec_designer import designer_material_icon +from csaxs_bec.bec_widgets.widgets.omny_alignment.omny_alignment import OmnyAlignment + +DOM_XML = """ + + + + +""" + + +class OmnyAlignmentPlugin(QDesignerCustomWidgetInterface): # pragma: no cover + def __init__(self): + super().__init__() + self._form_editor = None + + def createWidget(self, parent): + t = OmnyAlignment(parent) + return t + + def domXml(self): + return DOM_XML + + def group(self): + return "" + + def icon(self): + return designer_material_icon(OmnyAlignment.ICON_NAME) + + def includeFile(self): + return "omny_alignment" + + def initialize(self, form_editor): + self._form_editor = form_editor + + def isContainer(self): + return False + + def isInitialized(self): + return self._form_editor is not None + + def name(self): + return "OmnyAlignment" + + def toolTip(self): + return "OmnyAlignment" + + def whatsThis(self): + return self.toolTip() diff --git a/csaxs_bec/bec_widgets/widgets/omny_alignment/register_omny_alignment.py b/csaxs_bec/bec_widgets/widgets/omny_alignment/register_omny_alignment.py new file mode 100644 index 0000000..701fb7c --- /dev/null +++ b/csaxs_bec/bec_widgets/widgets/omny_alignment/register_omny_alignment.py @@ -0,0 +1,15 @@ +def main(): # pragma: no cover + from qtpy import PYSIDE6 + + if not PYSIDE6: + print("PYSIDE6 is not available in the environment. Cannot patch designer.") + return + from PySide6.QtDesigner import QPyDesignerCustomWidgetCollection + + from csaxs_bec.bec_widgets.widgets.omny_alignment.omny_alignment_plugin import OmnyAlignmentPlugin + + QPyDesignerCustomWidgetCollection.addCustomWidget(OmnyAlignmentPlugin()) + + +if __name__ == "__main__": # pragma: no cover + main() diff --git a/csaxs_bec/devices/ids_cameras/ids_camera.py b/csaxs_bec/devices/ids_cameras/ids_camera.py index c095ee8..37edadb 100644 --- a/csaxs_bec/devices/ids_cameras/ids_camera.py +++ b/csaxs_bec/devices/ids_cameras/ids_camera.py @@ -239,7 +239,7 @@ class IDSCamera(PSIDetectorBase): **kwargs, ): super().__init__( - prefix, name=name, kind=kind, parent=parent, device_manager=device_manager, **kwargs + prefix=prefix, name=name, kind=kind, parent=parent, device_manager=device_manager, **kwargs ) self.camera_ID = camera_ID self.bits_per_pixel = bits_per_pixel diff --git a/pyproject.toml b/pyproject.toml index c33d207..8ddb4b0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,8 +52,8 @@ plugin_scans = "csaxs_bec.scans" plugin_ipython_client_pre = "csaxs_bec.bec_ipython_client.startup.pre_startup" plugin_ipython_client_post = "csaxs_bec.bec_ipython_client.startup" -[project.entry-points."bec.widgets"] -plugin_widgets = "csaxs_bec.bec_widgets" +[project.entry-points."bec.widgets.user_widgets"] +plugin_widgets = "csaxs_bec.bec_widgets.widgets" [tool.hatch.build.targets.wheel] include = ["*"] -- 2.49.1