@@ -121,7 +121,7 @@ The `with` syntax is used by Trame to add content to a slot. This allows your vi
Here is a layout diagram showing all of the available slots in `ThemedApp`:


::::::::::::::::::::::::::::::::::::::::: callout
@@ -222,7 +222,7 @@ We\'ll add an `InputField` and a `VBoxLayout` to this tab.
We\'ll add a `GridLayout` and an `InputField` to this tab.
@@ -269,11 +286,89 @@ In `SampleTab1`, we\'ve used a `VBoxLayout` to vertically stack the `InputField`
To run the code, use the following command in the top level of your `nova_tutorial` project:
```bash
poetry run start
poetry run app
```
You should now see the simple UI. When you click the "Sample Tab 1" and "Sample Tab 2" tabs, you should now see the updated content with the new UI components.
Now that we understand the basics of working with Trame, let\'s make the view for the fractal tab a bit more intuitive for the user by giving them a visual indicator that the job is running.
We will need to add a data binding for `running`, as well. We choose to place this directly in the view model as this is not relevant to running the fractal tool on NDIP.
Finally, we manipulate our new view state based on the current status of the tool. Because the fractal tool takes a long time to complete, we offload it to a background thread. If we do not do this, then Trame will not update the view until the tool has finished running, which defeats the purpose of this change.
```python
defrun_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.
# We also need to know when the tool is done running so that we can
create_task(self.monitor_fractal())
defrun_fractal_in_background(self)->None:
self.model.fractal.run_fractal_tool()
self.running=False
asyncdefmonitor_fractal(self)->None:
whileself.running:
awaitsleep(0.1)
self.update_view()
```
::::::::::::::::::::::::::::::::: callout
With any Trame or `nova-trame` component, you can use the `v_if`, `v_else_if`, and `v_else` arguments to only show the component in the interface when a condition is true. The condition can be a reference to your model, similar to the `v_model` argument, or it can be a full JavaScript expression for complex use cases.
:::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::: callout
One major caveat when working with Trame is that Trame itself runs in the main thread of your application. Since Trame is responsible for syncing state between the server and the user interface, if you run a long, CPU-bound task in the main thread then Trame will freeze and your user interface will likely crash. If you need to run a long job (for example, a Mantid command that takes several minutes), then it is your responsibility to ensure that the task is run in a separate thread.
:::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::: challenge
**Explore the `InputField` Component**
Modify the `InputField` component in `SampleTab1` to automatically retrieve the label, hint, and validation rules from a Pydantic model field. Create a simple Pydantic model with a `username` field with a `title`, `description`, and `min_length` constraint.
***What is your Python package name (use Python naming conventions)?**
> Press enter to accept the default.
***Do you want to install Mantid for your project?**
> Enter `no`
*** Are you developing a GUI application using MVVM pattern?**
> Enter `yes`
*** Which library will you use?**
> Select `Trame`
***Do you want a template with multiple tabs?
> Enter `yes`
***Publish to PyPI?**
> Enter `no`
***Publish documentation to readthedocs.io?**
> Enter `no`
```bash
cd viz_tutorial
poetry install
poetry run app
@@ -56,7 +91,7 @@ The pandas install is only necessary for loading example data from Plotly, which
Now, we can create a view that displays a Plotly figure.
**1. `PlotlyView` View Class (`src/nova_tutorial/views/plotly.py`):**
**1. `PlotlyView` View Class (`src/viz_examples/views/plotly.py`):**
***Imports**: Pay special attention to the plotly import. This module contains a Trame widget that will allow us to quickly add a Plotly chart to our view.
@@ -116,7 +151,7 @@ class PlotlyView:
As with our previous examples, there is a corresponding model.
**2. `PlotlyConfig` Model Class (src/nova_tutorial/models/plotly.py):**
**2. `PlotlyConfig` Model Class (src/viz_examples/models/plotly.py):**
***Imports**: The graph_objects module is how we will define the content for our chart. The iris module defines an example dataset.
@@ -183,7 +218,7 @@ class PlotlyConfig(BaseModel):
First, let's add replace the sample tabs from the template with the following:
**7. `PyVistaConfig` Model Class (`src/nova_tutorial/models/pyvista.py`):**
**7. `PyVistaConfig` Model Class (`src/viz_examples/models/pyvista.py`):**
***Imports:**`download_knee_full` yields a 3D dataset that is suitable for volume rendering. You can find more datasets in PyVista\'s [Dataset Gallery](https://docs.pyvista.org/api/examples/dataset_gallery).
@@ -368,7 +403,7 @@ PyVista\'s volume rendering engine isn\'t currently suitable for large data. If
@@ -448,7 +483,7 @@ PyVista isn't compatible with VTK 9.4, yet. If you are not using PyVista, there
Once more, let's setup a view and model.
**11. `VTKView` View Class (`src/nova_tutorial/views/vtk.py`):**
**11. `VTKView` View Class (`src/viz_examples/views/vtk.py`):**
***Imports:** The `vtkRenderingVolumeOpenGL2` import is necessary despite being unreferenced.
@@ -509,7 +544,7 @@ class VTKView:
self.render_window.Render()
```
**12. `VTKConfig` Model Class (`src/nova_tutorial/models/vtk.py`):**
**12. `VTKConfig` Model Class (`src/viz_examples/models/vtk.py`):**
***Imports:** We are only using PyVista to get an example dataset. There are two references to it as we use `KNEE_DATA` to compute min/max bounds for the data and `KNEE_DATAFILE` to pass the data file into a VTK reader. The FixedPointVolumeRayCastMapper is CPU-based, but other mappers are available if you need GPU support.
@@ -641,7 +676,7 @@ class VTKConfig:
This is very similar to the Plotly and PyVista setup.