Source code for pyqt_reactive.widgets.shared.form_window_action_header

"""Reusable form-window header with staged action wrapping."""

from __future__ import annotations

from dataclasses import dataclass
from typing import Sequence

from PyQt6.QtGui import QFont
from PyQt6.QtWidgets import (
    QHBoxLayout,
    QLabel,
    QSizePolicy,
    QWidget,
)

from pyqt_reactive.widgets.shared.responsive_layout_widgets import StagedWrapLayout


[docs] @dataclass(frozen=True, slots=True) class HeaderAction: """A stable widget reference inside a form-window action group.""" id: str widget: QWidget
[docs] @dataclass(frozen=True, slots=True) class HeaderActionGroup: """A named action group for staged header wrapping.""" id: str actions: Sequence[HeaderAction]
[docs] class FormWindowActionHeader(QWidget): """Render a form title plus grouped actions with staged wrapping."""
[docs] def __init__( self, *, title_text: str, action_groups: Sequence[HeaderActionGroup], stay_priority: Sequence[str], right_aligned_group_ids: Sequence[str] = (), title_color: str | None = None, title_background: str = "transparent", parent: QWidget | None = None, ) -> None: super().__init__(parent) self.header_label = self._build_title_label( title_text=title_text, title_color=title_color, title_background=title_background, ) self.actions = { action.id: action.widget for group in action_groups for action in group.actions } title_group = self._group_widgets([self.header_label]) groups = [("title", title_group)] groups.extend( (group.id, self._group_widgets([action.widget for action in group.actions])) for group in action_groups ) self._layout_widget = StagedWrapLayout(parent=self) self._layout_widget.set_groups( groups, ["title", *stay_priority], right_align_names=right_aligned_group_ids, ) layout = QHBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self._layout_widget)
[docs] def action(self, action_id: str) -> QWidget: """Return a stable action widget by ID.""" return self.actions[action_id]
@staticmethod def _build_title_label( *, title_text: str, title_color: str | None, title_background: str, ) -> QLabel: label = QLabel(title_text) label.setFont(QFont("Arial", 14, QFont.Weight.Bold)) label.setWordWrap(True) label.setMinimumWidth(0) label.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed) if title_color is not None: label.setStyleSheet( f"color: {title_color}; background-color: {title_background};" ) return label @staticmethod def _group_widgets(widgets: Sequence[QWidget]) -> QWidget: group = QWidget() layout = QHBoxLayout(group) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(4) for widget in widgets: layout.addWidget(widget) return group