Unable to navigate to two page, one after another in a function #4096
-
QuestionI'm trying to navigate to one page "Loading" in the beggining of the code and then at the end of the code, i'm trying to navigate to another page. Here's the code: async def load_sbom_file(self):
if len(self.file_list):
print('Inside load_sbom_file')
ui.navigate.to('/loading_cpe')
print("Navigating to '/loading_cpe' before background tasks are started.")
await asyncio.sleep(1)
self.loading_thread_task(self.file_list)
else:
print("No file selected")
ui.notify("No file selected to load.", type="negative")
def loading_thread_task(self, list_of_files):
print("Inside loading_thread_task")
try:
logging.info("loading_thread_task started")
self.invalid_component_lno = []
if(self.validateSBOM(list_of_files) == False):
print("Provided SBOM(s) is not valid please check the logs!!")
logging.error("Provided SBOM(s) is not valid please check the logs!!")
thread1 = Thread(target=self.add_or_edit_sbom, args=(list_of_files, self.invalid_component_lno))
thread1.start()
print("add or edit sbom file_name: finisehd" )
print("end of loading_thread_task")
thread_check_loading_add_or_edit = Thread(target=self.check_loading_add_or_edit)
thread_check_loading_add_or_edit.start()
self.check_loading_event.join()
print("Navigating to '/addEdit' after background task is complete.")
ui.navigate.to('/addEdit')
return
except Exception as err:
print("Error in function loading_thread_task:\n", str(err))
logging.error("Error in function loading_thread_task Error: "+str(err)) |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 9 replies
-
Can you, please, try to create a minimum reproducible code example? This would allow us and the community to help more efficiently. Thanks! |
Beta Was this translation helpful? Give feedback.
-
Sure, here i have updated the code. I'm unable to navigate to /addEdit after navigating to /loading_cpe: from nicegui import ui
import asyncio
from threading import Thread, Event
class SBOMHandler:
def __init__(self):
self.check_loading_event = Event()
self.load_add_edit = False
async def load_sbom_file(self):
print('Inside load_sbom_file')
ui.navigate.to('/loading_cpe') # Navigate to loading page
print("Navigating to '/loading_cpe' before background tasks are started.")
await asyncio.sleep(1) # Simulate some initial delay
self.loading_thread_task()
def loading_thread_task(self):
print("Inside loading_thread_task")
try:
# Simulating background processing
thread = Thread(target=self.simulate_processing)
thread.start()
# Wait for the processing to complete
self.check_loading_event.wait()
print("Navigating to '/addEdit' after background task is complete.")
ui.navigate.to('/addEdit') # Navigate to AddEdit page
print("Navigated to '/addEdit'")
except Exception as err:
print("Error in function loading_thread_task:\n", str(err))
def simulate_processing(self):
print("Simulating background processing...")
# Simulate some processing time
import time
time.sleep(3)
self.load_add_edit = True # Indicate task completion
self.check_loading_event.set() # Signal that processing is complete
@ui.page('/loading_cpe')
def loading_cpe():
with ui.column().style('align-items: center; justify-content: center; height: 100vh;'):
ui.label('Loading... Please wait.').style('font-size: 20px; color: #333;')
ui.spinner(size=40)
@ui.page('/addEdit')
def add_edit():
with ui.column().style('align-items: center; justify-content: center; height: 100vh;'):
ui.label('Welcome to Add/Edit Page').style('font-size: 20px; color: #333;')
# Instantiate and trigger the process
handler = SBOMHandler()
ui.button('Start Process', on_click=handler.load_sbom_file)
ui.run() |
Beta Was this translation helpful? Give feedback.
-
Thanks! A quick fix would be to ask the check_loading_event = Event()
async def load():
ui.navigate.to('/loading')
await asyncio.sleep(1)
thread = Thread(target=simulate_processing)
thread.start()
check_loading_event.wait()
for client in app.clients('/loading'): # <-- here
with client:
ui.navigate.to('/done')
def simulate_processing():
time.sleep(3)
check_loading_event.set()
@ui.page('/loading')
def loading():
ui.label('Loading...')
@ui.page('/done')
def done():
ui.label('Done')
ui.button('Load', on_click=load) By the way, I'd recommend using NiceGUI's run module for multithreading and multiprocessing. This way you can simply await its completion and don't have to deal with events yourself: async def load():
ui.navigate.to('/loading')
await asyncio.sleep(1)
await run.io_bound(simulate_processing)
for client in app.clients('/loading'):
with client:
ui.navigate.to('/done')
def simulate_processing():
time.sleep(3) Last but not least, I would check if you can start the IO-bound process on the "/loading" page. This way you don't have to send navigation commands from one context to another: def simulate_processing():
time.sleep(3)
@ui.page('/loading')
async def loading():
ui.label('Loading...')
await ui.context.client.connected()
await run.io_bound(simulate_processing)
ui.navigate.to('/done')
@ui.page('/done')
def done():
ui.label('Done')
ui.button('Load', on_click=lambda: ui.navigate.to('/loading')) Note that we need to And if the process is CPU-bound rather than IO-bound, |
Beta Was this translation helpful? Give feedback.
-
I wonder why you want to switch pages in the first place. Normally, when loading you can simply show a progress popup or replace the content of the page. |
Beta Was this translation helpful? Give feedback.
You can copy the new
clients()
method into your code and use it: