pyqt_reactive.animation
Animation and visual effects system.
Game-engine inspired flash animation system with O(1) per-window performance for visual feedback on value changes.
- class pyqt_reactive.animation.FlashConfig(base_color_rgb: Tuple[int, int, int] = (255, 255, 255), flash_alpha: int = 255, fade_in_s: float = 0.2, hold_s: float = 0.05, fade_out_s: float = 0.6, frame_ms: int | None = None, use_opengl: bool = False, target_fps: int | None = None, max_fps: int | None = 60)[source]
Flash animation tuning knobs with automatic screen refresh rate detection.
- pyqt_reactive.animation.get_flash_config() FlashConfig[source]
Return singleton flash config.
- pyqt_reactive.animation.FlashMixin
alias of
VisualUpdateMixin
- class pyqt_reactive.animation.WindowFlashOverlay(window: QWidget)[source]
Transparent overlay that renders ALL flash effects for an entire window.
TRUE GAME ENGINE ARCHITECTURE: - ONE instance per top-level window (QMainWindow/QDialog) - Renders ALL element types (groupboxes, tree items, list items) in ONE paintEvent - Elements register via FlashElement with geometry callbacks - Scales O(1) per window regardless of element count or type
VIEWPORT CULLING: Elements outside visible scroll areas return None from their geometry callback and are skipped.
- classmethod get_for_window(widget: QWidget) WindowFlashOverlay | None[source]
Get or create the overlay for a top-level window (factory method).
Automatically chooses between OpenGL and QPainter based on config and availability.
Returns None if: - Widget is not yet in a proper window hierarchy - Widget has been deleted (RuntimeError from Qt C++ layer)
- classmethod cleanup_window(window: QWidget) None[source]
Remove overlay for a window (call when window closes).
- register_element(element: FlashElement) None[source]
Register a flashable element. Multiple elements can share the same key.
CRITICAL: Deduplicate based on (key, source_id) to prevent duplicate registrations while allowing multiple element types (tree item + groupbox) for the same key.
- invalidate_cache()[source]
Public method to invalidate geometry cache.
Call this when programmatically scrolling (e.g., scroll_to_section via tree item click).
- classmethod invalidate_cache_for_widget(widget: QWidget) None[source]
Invalidate geometry cache for the overlay covering a widget’s window.
Convenience method for programmatic scroll/resize operations.
- is_element_in_viewport(key: str) bool[source]
Check if any element for this key is visible (for viewport culling).
- class pyqt_reactive.animation.OverlayGeometryCache(valid: bool = False, scroll_clip_rects: List[QRect] = <factory>, element_rects: Dict[str, ~typing.List[~typing.Tuple[~PyQt6.QtCore.QRect, float] | None]]=<factory>, element_regions: Dict[str, ~typing.List[~PyQt6.QtGui.QPainterPath | None]]=<factory>)[source]
Unified cache for all overlay geometry calculations.
FIX 3: Single cache object with single invalidation point. Replaces separate scroll_area + element caches.
- pyqt_reactive.animation.get_flash_color(opacity: float = 1.0, config: FlashConfig | None = None, base_color: QColor | None = None) QColor[source]
Get the shared flash QColor with optional opacity (0.0-1.0).
- pyqt_reactive.animation.get_flash_color_from_palette(scope_id: str, alpha: int = 255, use_parent_scope: bool = True) QColor[source]
Get flash color from circular palette based on scope_id.
- Parameters:
scope_id – Scope identifier (e.g., “plate::config_field”)
alpha – Alpha channel (0-255)
use_parent_scope – If True, hash only parent scope (plate path) so all elements in same plate get same color. If False, hash full scope_id.
- Returns:
QColor from pre-computed WCAG-compliant palette
- class pyqt_reactive.animation.FlashElement(key: str, get_rect_in_window: Callable[[QWidget], QRect | None], get_child_rects: Callable[[QWidget], List[Tuple[QRect, bool]]] | None = None, needs_scroll_clipping: bool = True, source_id: str | None = None, corner_radius: float = 0.0, skip_overlay_paint: bool = False, delegate_widget: QWidget | None = None, get_model_index: Callable[[], Any] | None = None)[source]
Abstract representation of a flashable UI element.
Provides a geometry callback that returns the element’s rect in window coords. Works for ANY element type: groupboxes, tree items, list items, etc.
- __init__(key: str, get_rect_in_window: Callable[[QWidget], QRect | None], get_child_rects: Callable[[QWidget], List[Tuple[QRect, bool]]] | None = None, needs_scroll_clipping: bool = True, source_id: str | None = None, corner_radius: float = 0.0, skip_overlay_paint: bool = False, delegate_widget: QWidget | None = None, get_model_index: Callable[[], Any] | None = None) None
- pyqt_reactive.animation.get_widget_corner_radius(widget: QWidget) float[source]
Extract corner radius from widget’s stylesheet, with caching.
Searches the widget and its ancestors for border-radius in stylesheets. Returns 0 if no border-radius found (sharp corners).
Modules
Declarative configuration for flash animations. |
|
Unified visual update mixin for PyQt widgets. |