pythonnicegui

Importing Python files based on radio input


I want to import certain files based on input from the user using some sort of selection (I am using a radio button). I am having trouble getting the updated selection from the user to send to check the input and go to the desired page for the selection while importing the desired classes from another Python file in the process.

For example, suppose from another file scriptA.py, I have the class:

class A:
   def __init__(self, a):
      self.a = a

and from scriptB.py I have the class

class B:
   def __init__(self, b):
      self.b = b

In my app script app.py, I want to obtain the input for the user and given the input, go to the desired page and importing the class for the input:

class ImportSelection:
   def __init__(self, selection = None):
      self.selection = selection

importselection = ImportSelection()
ui.radio(['A', 'B']).bind_value(importselection, 'selection')

@ui.page('/A')
def page_A():
   from scriptA import A
   # do stuff

@ui.page('/B'):
def page_B():
   from scriptB import B
   # do stuff


if importselection.selection == 'A':
   ui.link("/A", page_A)
elif importselection.selection == 'B':
   ui.link("/B", page_B)

ui.run()

I am having trouble getting the user input to then go to the page. How should I refactor this code to do this? Thank you in advance!


Solution

  • There are multiple issues with your app code:

    1. Why your links are not created: NiceGUI works based on callbacks so code outside of a callback only happens once. When the code initially runs, importselection.selection is None and the links are not created.
    2. The navigation: ui.link created HTML links and does not navigate. You need ui.open
    3. Binding to the radio buttons: You need to create a callback that will happen when the value of the radio selection changes. This is done by setting on_change in the radio element.

    Here is a working example (that requires your scriptA.py and scriptB.py to exist):

    from nicegui import ui
    
    
    @ui.page('/A')
    def page_A():
        from scriptA import A
        ui.link('back', '/')
    
    
    @ui.page('/B')
    def page_B():
        from scriptB import B
        ui.link('back', '/')
    
    
    routing_map = {
        'A': page_A,
        'B': page_B,
    }
    ui.radio(
        list(routing_map.keys()), 
        on_change=lambda e: ui.open(routing_map[e.value])
    )
    
    ui.run()