Initial Commit
This commit is contained in:
commit
4dbdc7d793
18 changed files with 2384 additions and 0 deletions
127
pyqt6_scaffold/core/composer.py
Normal file
127
pyqt6_scaffold/core/composer.py
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
from .objects import NavigateRequest
|
||||
from .windows import BaseWindow
|
||||
from .logging import setup_logger
|
||||
from .database import AbstractDatabase
|
||||
from PyQt6.QtWidgets import QApplication
|
||||
from PyQt6.QtCore import QObject, pyqtSignal, pyqtSlot
|
||||
from typing import Dict
|
||||
|
||||
log = setup_logger(__name__)
|
||||
|
||||
class Composer(QObject):
|
||||
"""
|
||||
Application router and window lifecycle manager.
|
||||
|
||||
Manages window registration, navigation between windows,
|
||||
and holds the active database connection. Acts as the
|
||||
central hub of the application.
|
||||
|
||||
Args:
|
||||
app: QApplication instance.
|
||||
db: Connected AbstractDatabase instance.
|
||||
"""
|
||||
navigate_request = pyqtSignal(NavigateRequest)
|
||||
|
||||
def __init__(self, app: QApplication, db: AbstractDatabase):
|
||||
super().__init__()
|
||||
self._db = db
|
||||
self._current = None
|
||||
self._app = app
|
||||
self._registry: Dict[str, Dict[str, object]] = dict()
|
||||
self._current_ctx: Dict[str, Dict[str, object]] = dict()
|
||||
|
||||
self.navigate_request.connect(self.navigate)
|
||||
|
||||
@property
|
||||
def context(self):
|
||||
"""
|
||||
Return the current navigation context.
|
||||
"""
|
||||
return self._current_ctx
|
||||
|
||||
def register(self, name: str,
|
||||
window: type[BaseWindow],
|
||||
lazy: bool = True):
|
||||
"""
|
||||
Register a window class under a given name.
|
||||
|
||||
Args:
|
||||
name: Unique string identifier for the window.
|
||||
window: A subclass of BaseWindow.
|
||||
lazy: If True, the window is instantiated on first navigation.
|
||||
If False, the window is instantiated immediately.
|
||||
|
||||
Raises:
|
||||
TypeError: If window is not a subclass of BaseWindow.
|
||||
"""
|
||||
if not issubclass(window, BaseWindow):
|
||||
raise TypeError(f"{window} is not a descendant of BaseWindow")
|
||||
|
||||
entry = {
|
||||
"class": window,
|
||||
"instance": None,
|
||||
"lazy": lazy
|
||||
}
|
||||
|
||||
if not lazy:
|
||||
entry["instance"] = window(self, self._db)
|
||||
|
||||
self._registry[name] = entry
|
||||
|
||||
def _switch_window(self, window):
|
||||
"""
|
||||
Close the current window and show the new one.
|
||||
"""
|
||||
if self._current:
|
||||
self._current.close()
|
||||
self._current = window
|
||||
self._current.show()
|
||||
|
||||
def _create_window(self, name: str) -> BaseWindow:
|
||||
"""
|
||||
Instantiate or retrieve the window registered under name.
|
||||
|
||||
For lazy windows, creates a new instance on every call.
|
||||
For eager windows, returns the existing instance.
|
||||
"""
|
||||
entry = self._registry[name]
|
||||
|
||||
if not entry["lazy"]:
|
||||
return entry["instance"]
|
||||
|
||||
instance = entry["class"](self, self._db)
|
||||
return instance
|
||||
|
||||
@pyqtSlot(NavigateRequest)
|
||||
def navigate(self, request: NavigateRequest):
|
||||
"""
|
||||
Handle a NavigateRequest signal and switch to the target window.
|
||||
|
||||
Raises:
|
||||
KeyError: If the target window is not registered.
|
||||
"""
|
||||
if request.target not in self._registry:
|
||||
raise KeyError("Window is not registered")
|
||||
|
||||
self._current_ctx = request.context
|
||||
window = self._create_window(request.target)
|
||||
self._switch_window(window)
|
||||
|
||||
def run(self, start: str):
|
||||
"""
|
||||
Start the application from the given window.
|
||||
|
||||
Args:
|
||||
start: Name of the window to show first.
|
||||
|
||||
Raises:
|
||||
KeyError: If the start window is not registered.
|
||||
"""
|
||||
if start not in self._registry:
|
||||
raise KeyError("Window is not registered")
|
||||
|
||||
window = self._create_window(start)
|
||||
self._switch_window(window)
|
||||
return self._app.exec()
|
||||
Loading…
Add table
Add a link
Reference in a new issue