Streamlit 动态 UI,可根据不同输入小部件的值生成动态输入小部件

Streamlit dynamic UI to generate dynamic input widgets depending on value from a different input widget

提问人:Subaru Spirit 提问时间:2/8/2023 最后编辑:Subaru Spirit 更新时间:2/10/2023 访问量:1543

问:

我想打开这篇文章,因为我在 streamlit 的官方文档或任何提到如何执行此操作的资源上找不到任何内容。经过一番反复试验,我找到了一种方法,并将在下面发布答案。这是一个在 R shiny 中称为动态 UI 的功能,这里有一个问题。

如何根据不同输入小部件的值生成动态输入小部件?例如,如下图所示,被调用产品代码的编号取决于被调用产品代码的值。因此,如果有 x 个产品,则动态生成 x 个产品。此外,还可以提取生成的值。text_inputinumber_inputNumber of Productstext_inputtext_input

enter image description here

python streamlit 变量动态 ui

评论


答:

1赞 Subaru Spirit 2/8/2023 #1

这是执行此操作的一种方法。
首先,使用列表推导来存储键(用于稍后从text_input中提取值的变量)和值(text_input)。
接下来,使用 key 和 value 在类中设置属性。 例如,可以使用类中的属性提取标记为 product2 的text_input值。
p.product2

import streamlit as st

number_of_products = st.sidebar.number_input(label="Number of Products",
                                     min_value=0, max_value=20, value=1)

class Products:
    pass

p = Products()
keys = [str("product"+str(x+1)) for x in range(number_of_products)]
values = [st.sidebar.text_input(label=f"Product Code {x+1}", value=0) for x in range(number_of_products)]

for key, value in zip(keys, values):
    setattr(p, key, value)

# each key's value is stored in the class as an attribute
st.write(p.product2)

使用 dictionary 和 exec 命令也可以动态声明变量,但是当text_input里面的值不是数字时,就会产生错误。

0赞 Doracahl 2/10/2023 #2

使用 streamlit 的会话状态时,可以生成动态输入小部件内容。但是,在输入小部件交互时,streamlit 刷新页面存在一个潜在的缺点。

解决此问题的一种方法是创建多个表单。例如,在您的案例中,您可以为“产品数量”创建一个表单,并将此值更新为会话状态。

接下来,您可以创建另一个表单,该表单采用此“产品数量”参数并创建 x 个输入小部件。

import streamlit as st

with st.form("Number of Products"):
  numProducts = st.number_input('Insert a number', key='numProducts')
  submitForm = st.form_submit_button("Set Product Number")

  if submitForm:
    st.success("Please assign product codes below")

if 'numProducts' in st.session_state.keys():
  with st.form("Product Codes"):
    for i in range(st.session_state['numProducts']):
      # insert text inputs with keys here

希望这有帮助!