UI updates during trame__busy state #710
-
|
My original code is intended to click a button and then move in the UI from one camera point in pyvista to the next. However this fails because trame only updates the camera view or any UI element after it is not busy anymore. Even if I flash the state. Is there a way to update the UI while a function is still running? I tried different ways but it never worked. In the example below it should do a very simple thing. Update the text field with the values as they are set. How can I achieve this? Example code: from trame.app import get_server
from trame.ui.vuetify3 import SinglePageLayout
from trame.widgets import vuetify3, html
import time
server = get_server()
state, ctrl = server.state, server.controller
state["ready"] = False
state["vrg_idx"] = -1
view_point_pyvista = [0, 1, 2, 3, 4, 5, 6]
@state.change("vrg_idx")
def change_vrg_idx(vrg_idx, *args, **kwargs):
with state:
if not state["ready"]:
return
print(f"into change_vrg_idx, {vrg_idx=}")
_ = view_point_pyvista[int(vrg_idx)]
time.sleep(5)
if int(state["vrg_idx"]) < 5:
state["vrg_idx"] = int(state["vrg_idx"]) + 1
state["logs"] = state["logs"] + '\n' + str(state["vrg_idx"])
state.dirty("logs")
def walk():
"""function to be triggered to walk through a 3d model"""
state["ready"] = True
state["vrg_idx"] = 0
with SinglePageLayout(server) as layout:
with layout.toolbar:
vuetify3.VSpacer()
vuetify3.VBtn(
"Start Analysis",
click=walk,
)
vuetify3.VProgressLinear(
indeterminate=True,
absolute=True,
bottom=True,
active=("trame__busy",),
)
with (
layout.content,
vuetify3.VContainer(
fluid=True,
classes="pa-0 fill-height",
),
):
field = vuetify3.VTextarea(
label="Logs",
v_model=("logs", ""),
)
if __name__ == "__main__":
server.start() |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
|
You have several issue here. The first one is that you use @state.change to handle a recursive call with progress. But like you notice, only once everything got stable (no more change) they got synched with the client. Here is an example on how you could do what you wanted async def process_vrg_idx(vrg_idx):
if not state.ready:
return
print(f"into change_vrg_idx, {vrg_idx=}")
_ = view_point_pyvista[int(vrg_idx)]
await asyncio.sleep(5)
if vrg_idx < 5:
asyncio.create_task(process_vrg_idx(vrg_idx+1)
with state:
state.logs += f'\n{vrg_idx}'
def walk():
state.ready = True
asyncio.create_task(process_vrg_idx(0)) |
Beta Was this translation helpful? Give feedback.
You have several issue here.
The first one is that you use @state.change to handle a recursive call with progress. But like you notice, only once everything got stable (no more change) they got synched with the client.
The second one, if you want to dynamically update the client while you do things in the background without being busy, you need to use async tasks.
Here is an example on how you could do what you wanted