From 86b7aec64352f28f3ce22d12502563e855ed8a5b Mon Sep 17 00:00:00 2001 From: wyzula-jan Date: Sun, 6 Apr 2025 18:19:07 +0200 Subject: [PATCH] WIP launch window change of inheritance --- bec_widgets/applications/launch_window.py | 113 +++--------------- .../containers/main_window/main_window.py | 76 ++---------- 2 files changed, 23 insertions(+), 166 deletions(-) diff --git a/bec_widgets/applications/launch_window.py b/bec_widgets/applications/launch_window.py index c72e0d89..60ec582c 100644 --- a/bec_widgets/applications/launch_window.py +++ b/bec_widgets/applications/launch_window.py @@ -1,133 +1,43 @@ import os -from bec_lib.logger import bec_logger -from qtpy.QtCore import QSize -from qtpy.QtGui import QAction, QActionGroup -from qtpy.QtWidgets import QApplication, QMainWindow, QSizePolicy, QStyle +from qtpy.QtWidgets import QSizePolicy import bec_widgets +from bec_lib.logger import bec_logger from bec_widgets.cli.rpc.rpc_register import RPCRegister from bec_widgets.utils import UILoader -from bec_widgets.utils.bec_widget import BECWidget -from bec_widgets.utils.colors import apply_theme from bec_widgets.utils.container_utils import WidgetContainerUtils from bec_widgets.widgets.containers.dock.dock_area import BECDockArea -from bec_widgets.widgets.containers.main_window.addons.web_links import BECWebLinksMixin +from bec_widgets.widgets.containers.main_window.main_window import BECMainWindow logger = bec_logger.logger MODULE_PATH = os.path.dirname(bec_widgets.__file__) -class LaunchWindow(BECWidget, QMainWindow): +class LaunchWindow(BECMainWindow): def __init__(self, gui_id: str = None, *args, **kwargs): - QMainWindow.__init__(self, *args, **kwargs) - BECWidget.__init__(self, gui_id=gui_id, **kwargs) + BECMainWindow.__init__(self, gui_id=gui_id, window_title="BEC Launcher", *args, **kwargs) self.setObjectName("LaunchWindow") - self.app = QApplication.instance() - self.resize(500, 300) self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) + self.loader = UILoader(self) self._init_ui() def _init_ui(self): - # Set the window title - self.setWindowTitle("BEC Launcher") - + super()._init_ui() # Load ui file ui_file_path = os.path.join(MODULE_PATH, "applications/launch_dialog.ui") self.load_ui(ui_file_path) - # Set Menu and Status bar - self._setup_menu_bar() - - # BEC Specific UI - self._init_bec_specific_ui() - - # TODO can be implemented for toolbar def load_ui(self, ui_file): - loader = UILoader(self) - self.ui = loader.loader(ui_file) + self.ui = self.loader.loader(ui_file) self.setCentralWidget(self.ui) self.ui.open_dock_area.setText("Open Dock Area") self.ui.open_dock_area.clicked.connect(lambda: self.launch("dock_area")) - def _init_bec_specific_ui(self): - if getattr(self.app, "gui_id", None): - self.statusBar().showMessage(f"App ID: {self.app.gui_id}") - else: - logger.warning( - "Application is not a BECApplication instance. Status bar will not show App ID. Please initialize the application with BECApplication." - ) - - # Set the window icon - # FIXME this do not work - def list_app_hierarchy(self): - """ - List the hierarchy of the application. - """ - self.app.list_hierarchy() - - def _setup_menu_bar(self): - """ - Setup the menu bar for the main window. - """ - menu_bar = self.menuBar() - - ######################################## - # Theme menu - theme_menu = menu_bar.addMenu("Theme") - - theme_group = QActionGroup(self) - light_theme_action = QAction("Light Theme", self, checkable=True) - dark_theme_action = QAction("Dark Theme", self, checkable=True) - theme_group.addAction(light_theme_action) - theme_group.addAction(dark_theme_action) - theme_group.setExclusive(True) - - theme_menu.addAction(light_theme_action) - theme_menu.addAction(dark_theme_action) - - # Connect theme actions - light_theme_action.triggered.connect(lambda: self.change_theme("light")) - dark_theme_action.triggered.connect(lambda: self.change_theme("dark")) - - # Set the default theme - # TODO can be fetched from app - dark_theme_action.setChecked(True) - - ######################################## - # Help menu - help_menu = menu_bar.addMenu("Help") - - help_icon = QApplication.style().standardIcon(QStyle.SP_MessageBoxQuestion) - bug_icon = QApplication.style().standardIcon(QStyle.SP_MessageBoxInformation) - - bec_docs = QAction("BEC Docs", self) - bec_docs.setIcon(help_icon) - widgets_docs = QAction("BEC Widgets Docs", self) - widgets_docs.setIcon(help_icon) - bug_report = QAction("Bug Report", self) - bug_report.setIcon(bug_icon) - - bec_docs.triggered.connect(BECWebLinksMixin.open_bec_docs) - widgets_docs.triggered.connect(BECWebLinksMixin.open_bec_widgets_docs) - bug_report.triggered.connect(BECWebLinksMixin.open_bec_bug_report) - - help_menu.addAction(bec_docs) - help_menu.addAction(widgets_docs) - help_menu.addAction(bug_report) - - debug_bar = menu_bar.addMenu(f"DEBUG {self.__class__.__name__}") - list_hierarchy = QAction("List App Hierarchy", self) - list_hierarchy.triggered.connect(self.list_app_hierarchy) - debug_bar.addAction(list_hierarchy) - - def change_theme(self, theme): - apply_theme(theme) - def launch( self, launch_script: str, @@ -163,9 +73,16 @@ class LaunchWindow(BECWidget, QMainWindow): if geometry is not None: dock_area.setGeometry(*geometry) + # TODO somehow we need to encapsulate this into BECMainWindow and keep dock area as top widget + # window = BECMainWindow() + # window.setCentralWidget(dock_area) + # window.show() + # dock_area.parent_id = None dock_area.show() return dock_area + def custom_ui_launcher(self): ... + def show_launcher(self): self.show() diff --git a/bec_widgets/widgets/containers/main_window/main_window.py b/bec_widgets/widgets/containers/main_window/main_window.py index 03ad51e3..b281879f 100644 --- a/bec_widgets/widgets/containers/main_window/main_window.py +++ b/bec_widgets/widgets/containers/main_window/main_window.py @@ -1,13 +1,11 @@ import os -from typing import TYPE_CHECKING -from bec_lib.logger import bec_logger from qtpy.QtCore import QSize from qtpy.QtGui import QAction, QActionGroup, QIcon from qtpy.QtWidgets import QApplication, QMainWindow, QStyle import bec_widgets -from bec_widgets.cli.rpc.rpc_register import RPCRegister +from bec_lib.logger import bec_logger from bec_widgets.utils import UILoader from bec_widgets.utils.bec_widget import BECWidget from bec_widgets.utils.colors import apply_theme @@ -16,9 +14,6 @@ from bec_widgets.utils.error_popups import SafeSlot from bec_widgets.utils.widget_io import WidgetHierarchy from bec_widgets.widgets.containers.main_window.addons.web_links import BECWebLinksMixin -if TYPE_CHECKING: - from bec_widgets.widgets.containers.dock.dock_area import BECDockArea - logger = bec_logger.logger MODULE_PATH = os.path.dirname(bec_widgets.__file__) @@ -35,21 +30,25 @@ class BECMainWindow(BECWidget, QMainWindow): def _init_ui(self): + # Set the icon + self._init_bec_icon() + # Set Menu and Status bar self._setup_menu_bar() # BEC Specific UI - self.display_app_it() + self.display_app_id() def _init_bec_icon(self): icon = self.app.windowIcon() if icon.isNull(): + print("No icon is set, setting default icon") icon = QIcon() icon.addFile( os.path.join(MODULE_PATH, "assets", "app_icons", "bec_widgets_icon.png"), size=QSize(48, 48), ) - self.setWindowIcon(icon) + self.app.setWindowIcon(icon) else: print("An icon is set") @@ -58,7 +57,7 @@ class BECMainWindow(BECWidget, QMainWindow): self.ui = loader.loader(ui_file) self.setCentralWidget(self.ui) - def display_app_it(self): + def display_app_id(self): server_id = self.bec_dispatcher.cli_server.gui_id self.statusBar().showMessage(f"App ID: {server_id}") @@ -122,65 +121,6 @@ class BECMainWindow(BECWidget, QMainWindow): def change_theme(self, theme: str): apply_theme(theme) - # #FIXME I have zero idea what this is good for... - # def _dump(self): - # """Return a dictionary with informations about the application state, for use in tests""" - # # TODO: ModularToolBar and something else leak top-level widgets (3 or 4 QMenu + 2 QWidget); - # # so, a filtering based on title is applied here, but the solution is to not have those widgets - # # as top-level (so for now, a window with no title does not appear in _dump() result) - # - # # NOTE: the main window itself is excluded, since we want to dump dock areas - # info = { - # tlw.gui_id: { - # "title": tlw.windowTitle(), - # "visible": tlw.isVisible(), - # "class": str(type(tlw)), - # } - # for tlw in QApplication.instance().topLevelWidgets() - # if tlw is not self and tlw.windowTitle() - # } - # # Add the main window dock area - # info[self.centralWidget().gui_id] = { - # "title": self.windowTitle(), - # "visible": self.isVisible(), - # "class": str(type(self.centralWidget())), - # } - # return info - # - 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. - """ - from bec_widgets.widgets.containers.dock.dock_area import BECDockArea - - with RPCRegister.delayed_broadcast() as rpc_register: - existing_dock_areas = rpc_register.get_names_of_rpc_by_class_type(BECDockArea) - if name is not None: - if name in existing_dock_areas: - raise ValueError( - f"Name {name} must be unique for dock areas, but already exists: {existing_dock_areas}." - ) - else: - name = "dock_area" - name = WidgetContainerUtils.generate_unique_name(name, existing_dock_areas) - dock_area = WindowWithUi() # BECDockArea(name=name) - 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): super().close()