Исходный код EJIO.ctk_extender.layout.router
## /ctk_extender/layout/router.py
from collections.abc import Callable
from loguru import logger
from EJIO.utils import Registry, create_decorator
from EJIO.utils.err import RegistryKeyError, RegistryTypeError
from .base import Layout
from .err import LayoutNotFoundError, LayoutAlreadyRegisteredError, IncorrectLayoutTypeError
__all__ = [
'LayoutRouter',
'register_layout',
'get_layout',
]
[документация]
class LayoutRouter[T: Layout](Registry[Layout]):
"""
Статический реестр маршрутов макетов приложения.
Связывает строковый ключ 'окно:макет' с классом конкретного Layout.
"""
[документация]
@classmethod
def get(cls, key: str) -> type[T]:
try:
return super().get(key)
except RegistryKeyError:
raise LayoutNotFoundError(f"Layout {key} is not registered.")
[документация]
@classmethod
def get_layout_class(cls, window_name: str, layout_name: str) -> type[Layout]:
"""
Безопасно извлекает класс макета для указанного окна.
:param window_name: Имя управляющего окна (префикс).
:param layout_name: Имя целевого макета.
:return: Класс Layout.
"""
route = f"{window_name}:{layout_name}"
try:
return cls.get(route)
except LayoutNotFoundError:
logger.error(f"Route '{route}' is missing in layout registry.")
raise LayoutNotFoundError(f"Layout for route {route} is missing in layout registry.")
#register_layout: Callable[[str], Callable] = create_decorator(LayoutRouter)
[документация]
def register_layout[E: Layout](key: str) -> Callable[[type[E]], type[E]]:
"""
Декоратор для автоматической регистрации окон в LayoutRouter.
:param key: Ключ, под которым объект будет храниться в реестре.
:return: Обертку, выполняющую регистрацию класса.
"""
def decorator(target_cls: type[E]) -> type[E]:
"""
Обертка, выполняющая регистрацию класса в реестр.
:param target_cls: Класс, который нужно зарегестрировать.
:return: Класс, который нужно зарегестрировать.
"""
try:
LayoutRouter.register(key, target_cls)
except RegistryTypeError:
raise IncorrectLayoutTypeError(f"Class {target_cls.__name__} is not a valid Layout type.")
except RegistryKeyError:
raise LayoutAlreadyRegisteredError(f"Layout {key} is already registered.")
return target_cls
return decorator #type: ignore[return-value]
[документация]
def get_layout(window_name: str, layout_name: str) -> type[Layout]:
"""
Безопасно извлекает класс макета для указанного окна.
:param window_name: Имя управляющего окна (префикс).
:param layout_name: Имя целевого макета.
:return: Класс Layout.
"""
return LayoutRouter.get_layout_class(window_name, layout_name)