[Python] How to get updated values in NiceGUI

Discussão em 'Python' iniciado por Stack, Novembro 27, 2024.

  1. Stack

    Stack Membro Participativo

    I'm writing a NiceGUI frontend for my Python code. This is my first time writing frontend, and I'm not very used to web-framework concepts.

    Essentially, the use of this frontend is to ask to user to insert the following variables (I know range is not a good variable name):

    variants_text: str
    keywords_text: str
    seed: int | None
    min_articles: int | None
    max_articles: int | None
    range: int | None
    limit: int | None


    This is the code I have written so far (the only dependecy is nicegui, and you need a dummy .txt file to pass Step1):

    from nicegui import ui

    class ArticleRetrieval:

    def __init__(self):

    self.page_title = "Article Retrieval"
    self.headers()

    self.stepper = ui.stepper().props("vertical").classes("w-full")

    self.step1_title = "Add input files"
    self.step2_title = "Add optional arguments"
    self.step3_title = "Retrieve articles"

    self.variants_uploaded = False
    self.variants_text = None

    self.keywords_uploaded = False
    self.keywords_text = None

    self.seed = None
    self.min_articles = None
    self.max_articles = None
    self.range = None
    self.limit = None

    self.positive_integer_validator = {
    "You can only insert a non-negative integer": self._acceptable_num
    }

    def _acceptable_num(self, n) -> bool:
    return (n is None) or (n == int(n) and n >=0)

    def _variants_uploaded(self, e):
    self.variants_uploaded = True
    self.variants_text = e.content.readlines()
    if self.keywords_uploaded is True:
    self.step1_next_button.visible = True

    def _keywords_uploaded(self, e):
    self.keywords_uploaded = True
    self.keywords_text = e.content.readlines()
    if self.variants_uploaded is True:
    self.step1_next_button.visible = True

    def _update_seed(self, e):
    self.seed = e.value
    self._step2_next_button_visibility()

    def _update_min_articles(self, e):
    self.min_articles = e.value
    self._step2_next_button_visibility()

    def _update_max_articles(self, e):
    self.max_articles = e.value
    self._step2_next_button_visibility()

    def _update_range(self, e):
    self.range = e.value
    self._step2_next_button_visibility()

    def _update_limit(self, e):
    self.limit = e.value
    self._step2_next_button_visibility()

    def _step2_next_button_visibility(self):
    if all(
    self._acceptable_num(x) for x in [
    self.seed,
    self.min_articles,
    self.max_articles,
    self.max_articles,
    self.limit,
    ]
    ):
    self.step2_next_button.set_visibility(True)
    else:
    self.step2_next_button.set_visibility(False)

    def _ask_confirm(self):
    ui.markdown(
    f"""
    ##### DO YOU CONFIRM THIS DATA?<br>

    **variants**: {self.variants_text}<br>
    **keywords**: {self.keywords_text}<br>
    **seed**: {self.seed}<br>
    **min\\_articles**: {self.min_articles}<br>
    **max\\_articles**: {self.max_articles}<br>
    **range**: {self.range}<br>
    **limit**: {self.limit}<br>
    """
    )

    def headers(self):
    ui.page_title(self.page_title)
    ui.markdown(f"#{self.page_title}")

    def step1(self):
    with ui.step(self.step1_title):
    ui.upload(
    label="Variants (.txt file)",
    max_files=1,
    auto_upload=True,
    on_upload=self._variants_uploaded,
    ).props("accept=.txt").classes("max-w-full")

    ui.upload(
    label="Keywords (.txt file)",
    max_files=1,
    auto_upload=True,
    on_upload=self._keywords_uploaded,
    ).props("accept=.txt").classes("max-w-full")

    with ui.stepper_navigation():
    self.step1_next_button = ui.button(
    "NEXT",
    icon="arrow_forward_ios",
    on_click=self.stepper.next
    )
    self.step1_next_button.visible = False

    def step2(self):

    with ui.step(self.step2_title):

    ui.number(
    label="Seed",
    validation=self.positive_integer_validator,
    on_change=self._update_seed
    ).props("clearable")
    ui.number(
    label="Minimum articles",
    validation=self.positive_integer_validator,
    on_change=self._update_min_articles
    ).props("clearable")
    ui.number(
    label="Maximum articles",
    validation=self.positive_integer_validator,
    on_change=self._update_max_articles
    ).props("clearable")
    ui.number(
    label="Range",
    validation=self.positive_integer_validator,
    on_change=self._update_range
    ).props("clearable")
    ui.number(
    label="Limit",
    validation=self.positive_integer_validator,
    on_change=self._update_limit
    ).props("clearable")

    with ui.stepper_navigation():
    self.step2_back_button = ui.button(
    "BACK",
    icon="arrow_back_ios",
    on_click=self.stepper.previous,
    )
    self.step2_next_button = ui.button(
    "NEXT",
    icon="arrow_forward_ios",
    on_click=self.stepper.next
    )
    self.step2_next_button.visibility = False

    def step3(self):
    with ui.step(self.step3_title):
    self._ask_confirm()
    with ui.stepper_navigation():
    ui.button(
    "BACK",
    icon="arrow_back_ios",
    on_click=self.stepper.previous,
    )
    ui.button(
    "RUN",
    icon="rocket_launch",
    on_click=lambda x: None # HERE I WILL PERFORM THE ACTUAL JOB
    )

    def run(self):
    with self.stepper:
    self.step1()
    self.step2()
    self.step3()
    ui.run()

    ArticleRetrieval().run()


    My question is about the _ask_confirm method.
    It always prints the initial values of attributes, the ones I've defined in the __init__ method (i.e. all None).

    [​IMG]

    I would like that string to be updated every time I update values in Step1 and Step2.

    The thing I don't understand is that if, for example, I change the _update_seed method like this

    def _update_seed(self, e):
    print(self.seed)
    self.seed = e.value
    print(self.seed)
    self._step2_next_button_visibility()


    It prints the updated values.

    I hope someone can help me. Thank you very much.

    Continue reading...

Compartilhe esta Página