Loading code/episode_5/src/nova_tutorial/app/models/main_model.py +1 −1 Original line number Diff line number Diff line Loading @@ -22,5 +22,5 @@ class MainModel(BaseModel): examples=["user"], ) password: str = Field(default="test_password", title="User Password") fractal: Fractal = Field(default_factory=Fractal) file: str = Field(default="", title="Select a File") fractal: Fractal = Field(default_factory=Fractal) code/episode_5/src/nova_tutorial/app/view_models/main.py +22 −0 Original line number Diff line number Diff line """Module for the main ViewModel.""" from asyncio import create_task, sleep from threading import Thread from typing import Any, Dict from nova.mvvm.interface import BindingInterface Loading @@ -12,6 +14,7 @@ class MainViewModel: def __init__(self, model: MainModel, binding: BindingInterface): self.model = model self.running = False # here we create a bind that connects ViewModel with View. It returns a communicator object, # that allows to update View from ViewModel (by calling update_view). Loading @@ -19,6 +22,7 @@ class MainViewModel: # but one also can provide a callback function if they want to react to those events # and/or process errors. self.config_bind = binding.new_bind(self.model, callback_after_update=self.change_callback) self.running_bind = binding.new_bind() def change_callback(self, results: Dict[str, Any]) -> None: if results["error"]: Loading @@ -28,6 +32,24 @@ class MainViewModel: def update_view(self) -> None: self.config_bind.update_in_view(self.model) self.running_bind.update_in_view(self.running) def run_fractal(self) -> None: self.running = True self.update_view() # update_view won't take effect until this method returns a value, so we must offload this long-running task to # a background thread for our conditional rendering to work. fractal_tool_thread = Thread(target=self.run_fractal_in_background, daemon=True) fractal_tool_thread.start() create_task(self.monitor_fractal()) def run_fractal_in_background(self) -> None: self.model.fractal.run_fractal_tool() self.running = False async def monitor_fractal(self) -> None: while self.running: await sleep(0.1) self.update_view() code/episode_5/src/nova_tutorial/app/views/fractal_tab.py +9 −14 Original line number Diff line number Diff line Loading @@ -2,24 +2,19 @@ from trame.widgets import vuetify3 as vuetify from nova.trame.view.components import InputField from nova_tutorial.app.view_models.main import MainViewModel from nova.trame.view import layouts class FractalTab: def __init__(self, view_model: MainViewModel) -> None: self.view_model = view_model self.view_model.running_bind.connect("running") self.create_ui() def create_ui(self) -> None: with layouts.VBoxLayout(classes="ma-4"): with vuetify.VCard(classes="pa-4"): InputField( v_model=("config.fractal.fractal_type", "mandelbrot"), label="Fractal Type", ) InputField(v_model="config.fractal.fractal_type", classes="mb-2") vuetify.VProgressCircular(v_if="running", indeterminate=True) vuetify.VBtn( "Run Fractal", click=self.view_model.run_fractal, classes="mt-2", v_else=True, click=self.view_model.run_fractal, # calls the run_fractal_tool method ) vuetify.VCardText(v_text="config.status_message", classes="mt-2") No newline at end of file vuetify.VImg(src=("config.fractal.image_data",), height="400", width="400") code/episode_6/advanced_pydantic/src/advanced_pydantic/main.py +1 −1 Original line number Diff line number Diff line Loading @@ -41,7 +41,7 @@ def main() -> None: # Example input user_data = { "id": 2, "name": "Alice", "name": "alice", "addresses": [{"street": "123 Main St", "city": "New York", "zip_code": "10001", "type": "home"}], } Loading code/episode_6/pydantic_mvvm/src/trame_with_pydantic/app/view_models/main.py +1 −1 Original line number Diff line number Diff line Loading @@ -21,4 +21,4 @@ class MainViewModel: print(f"model fields updated: {results['updated']}") def update_view(self) -> None: self.settings_bind.update_view(self.settings) self.settings_bind.update_in_view(self.settings) Loading
code/episode_5/src/nova_tutorial/app/models/main_model.py +1 −1 Original line number Diff line number Diff line Loading @@ -22,5 +22,5 @@ class MainModel(BaseModel): examples=["user"], ) password: str = Field(default="test_password", title="User Password") fractal: Fractal = Field(default_factory=Fractal) file: str = Field(default="", title="Select a File") fractal: Fractal = Field(default_factory=Fractal)
code/episode_5/src/nova_tutorial/app/view_models/main.py +22 −0 Original line number Diff line number Diff line """Module for the main ViewModel.""" from asyncio import create_task, sleep from threading import Thread from typing import Any, Dict from nova.mvvm.interface import BindingInterface Loading @@ -12,6 +14,7 @@ class MainViewModel: def __init__(self, model: MainModel, binding: BindingInterface): self.model = model self.running = False # here we create a bind that connects ViewModel with View. It returns a communicator object, # that allows to update View from ViewModel (by calling update_view). Loading @@ -19,6 +22,7 @@ class MainViewModel: # but one also can provide a callback function if they want to react to those events # and/or process errors. self.config_bind = binding.new_bind(self.model, callback_after_update=self.change_callback) self.running_bind = binding.new_bind() def change_callback(self, results: Dict[str, Any]) -> None: if results["error"]: Loading @@ -28,6 +32,24 @@ class MainViewModel: def update_view(self) -> None: self.config_bind.update_in_view(self.model) self.running_bind.update_in_view(self.running) def run_fractal(self) -> None: self.running = True self.update_view() # update_view won't take effect until this method returns a value, so we must offload this long-running task to # a background thread for our conditional rendering to work. fractal_tool_thread = Thread(target=self.run_fractal_in_background, daemon=True) fractal_tool_thread.start() create_task(self.monitor_fractal()) def run_fractal_in_background(self) -> None: self.model.fractal.run_fractal_tool() self.running = False async def monitor_fractal(self) -> None: while self.running: await sleep(0.1) self.update_view()
code/episode_5/src/nova_tutorial/app/views/fractal_tab.py +9 −14 Original line number Diff line number Diff line Loading @@ -2,24 +2,19 @@ from trame.widgets import vuetify3 as vuetify from nova.trame.view.components import InputField from nova_tutorial.app.view_models.main import MainViewModel from nova.trame.view import layouts class FractalTab: def __init__(self, view_model: MainViewModel) -> None: self.view_model = view_model self.view_model.running_bind.connect("running") self.create_ui() def create_ui(self) -> None: with layouts.VBoxLayout(classes="ma-4"): with vuetify.VCard(classes="pa-4"): InputField( v_model=("config.fractal.fractal_type", "mandelbrot"), label="Fractal Type", ) InputField(v_model="config.fractal.fractal_type", classes="mb-2") vuetify.VProgressCircular(v_if="running", indeterminate=True) vuetify.VBtn( "Run Fractal", click=self.view_model.run_fractal, classes="mt-2", v_else=True, click=self.view_model.run_fractal, # calls the run_fractal_tool method ) vuetify.VCardText(v_text="config.status_message", classes="mt-2") No newline at end of file vuetify.VImg(src=("config.fractal.image_data",), height="400", width="400")
code/episode_6/advanced_pydantic/src/advanced_pydantic/main.py +1 −1 Original line number Diff line number Diff line Loading @@ -41,7 +41,7 @@ def main() -> None: # Example input user_data = { "id": 2, "name": "Alice", "name": "alice", "addresses": [{"street": "123 Main St", "city": "New York", "zip_code": "10001", "type": "home"}], } Loading
code/episode_6/pydantic_mvvm/src/trame_with_pydantic/app/view_models/main.py +1 −1 Original line number Diff line number Diff line Loading @@ -21,4 +21,4 @@ class MainViewModel: print(f"model fields updated: {results['updated']}") def update_view(self) -> None: self.settings_bind.update_view(self.settings) self.settings_bind.update_in_view(self.settings)