UI Integration ============== Examples of building reactive forms with pyqt-reactive. Basic Form Generation --------------------- Create a form from a dataclass: .. code-block:: python from dataclasses import dataclass from PyQt6.QtWidgets import QApplication from pyqt_reactive.forms import ParameterFormManager @dataclass class ProcessingConfig: input_path: str = "" output_path: str = "" num_workers: int = 4 enable_gpu: bool = False threshold: float = 0.5 app = QApplication([]) # Create form from dataclass form = ParameterFormManager(ProcessingConfig) form.show() # Collect values back as typed dataclass config = form.collect_values() print(f"Config: {config}") app.exec() Form with ObjectState Integration ---------------------------------- Bind a form to ObjectState for lazy configuration and inheritance: .. code-block:: python from dataclasses import dataclass from PyQt6.QtWidgets import QApplication from pyqt_reactive.forms import ParameterFormManager from objectstate import config_context, ObjectStateRegistry @dataclass class GlobalConfig: threshold: float = 0.5 iterations: int = 10 @dataclass class StepConfig: threshold: float = None # Inherit from global iterations: int = None # Inherit from global name: str = "step_0" app = QApplication([]) # Setup ObjectState context global_cfg = GlobalConfig(threshold=0.7, iterations=20) with config_context(global_cfg): # Create form - fields with None will show inherited values as placeholders form = ParameterFormManager(StepConfig) form.show() # Placeholder text shows: "0.7 (from GlobalConfig)" # User can override by entering a value app.exec() Reactive Field Updates ---------------------- Use FieldChangeDispatcher to react to field changes: .. code-block:: python from dataclasses import dataclass from PyQt6.QtWidgets import QApplication from pyqt_reactive.forms import ParameterFormManager from pyqt_reactive.services import FieldChangeDispatcher @dataclass class ImageConfig: width: int = 512 height: int = 512 aspect_ratio: str = "1:1" app = QApplication([]) form = ParameterFormManager(ImageConfig) dispatcher = FieldChangeDispatcher() # React to width changes def on_width_changed(event): print(f"Width changed to {event.value}") # Update aspect ratio or height dispatcher.subscribe("width", on_width_changed) form.show() app.exec() Theming and Styling ------------------- Apply themes to forms: .. code-block:: python from dataclasses import dataclass from PyQt6.QtWidgets import QApplication from pyqt_reactive.forms import ParameterFormManager from pyqt_reactive.theming import ColorScheme, apply_theme @dataclass class AppConfig: name: str = "MyApp" debug: bool = False app = QApplication([]) form = ParameterFormManager(AppConfig) # Apply dark theme apply_theme(form, ColorScheme.DARK) form.show() app.exec() Flash Animations ---------------- Visual feedback when values change: .. code-block:: python from dataclasses import dataclass from PyQt6.QtWidgets import QApplication from pyqt_reactive.forms import ParameterFormManager @dataclass class Config: value: float = 0.5 app = QApplication([]) form = ParameterFormManager(Config) # Flash animations automatically trigger on value changes # Provides visual feedback similar to React component updates form.show() app.exec() Window Management ----------------- Manage multiple windows with WindowManager: .. code-block:: python from dataclasses import dataclass from PyQt6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QPushButton from pyqt_reactive.services import WindowManager from pyqt_reactive.forms import ParameterFormManager @dataclass class Config: name: str = "default" class ConfigWindow(QMainWindow): def __init__(self, scope_id: str): super().__init__() self.scope_id = scope_id layout = QVBoxLayout() form = ParameterFormManager(Config) layout.addWidget(form) widget = QWidget() widget.setLayout(layout) self.setCentralWidget(widget) app = QApplication([]) # Show or focus window window = WindowManager.show_or_focus( "config:main", lambda: ConfigWindow("config:main") ) # Navigate to specific field WindowManager.navigate_to("config:main", field="name") app.exec() Service Registration -------------------- Register custom providers with pyqt-reactive: .. code-block:: python from pyqt_reactive.protocols import ( set_form_config, register_llm_service, register_codegen_provider, FormGenConfig ) # Configure form generation config = FormGenConfig() config.log_dir = "/tmp/logs" set_form_config(config) # Register custom LLM service class MyLLMService: def generate_pipeline(self, description: str) -> str: return "# Generated pipeline" register_llm_service(MyLLMService()) # Register custom code generator class MyCodegenProvider: def generate_code(self, config) -> str: return "# Generated code" register_codegen_provider(MyCodegenProvider()) Custom Widgets -------------- Create custom widgets that work with ParameterFormManager: .. code-block:: python from PyQt6.QtWidgets import QWidget, QVBoxLayout, QLabel, QSlider from PyQt6.QtCore import Qt, pyqtSignal from pyqt_reactive.protocols import ValueGettable, ValueSettable class CustomSliderWidget(QWidget, ValueGettable, ValueSettable): """Custom slider widget with label.""" value_changed = pyqtSignal(int) def __init__(self): super().__init__() layout = QVBoxLayout() self.label = QLabel("0") self.slider = QSlider(Qt.Orientation.Horizontal) self.slider.setRange(0, 100) self.slider.valueChanged.connect(self._on_value_changed) layout.addWidget(self.label) layout.addWidget(self.slider) self.setLayout(layout) def get_value(self): return self.slider.value() def set_value(self, value): self.slider.setValue(int(value)) def _on_value_changed(self, value): self.label.setText(str(value)) self.value_changed.emit(value)