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

huangapple go评论78阅读模式
英文:

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

问题

我想要打开这篇帖子,因为我在Streamlit的官方文档或任何资源中都找不到有关如何实现这一功能的信息。经过一些试错,我已经找到了一种方法,并将在下面发布答案。这是在R Shiny中称为动态UI的功能,以下是问题。

如何根据不同输入小部件的值生成动态输入小部件?例如,如下图片所示,名为Product Code itext_input的数量取决于名为Number of Products的number_input的值。因此,如果有x个产品,就会动态生成x个text_input。此外,还可以提取生成的text_input中的值。

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

英文:

I want to open this post as I can't find anything on the official documentation from streamlit or any resources that mentioned how to do this. After some trial and error I have figured out a way, and will post the answer below. This is a function that in R shiny is called dynamic UI, here's the question.

How to generate dynamic input widgets depending on the value from a different input widget? For example see below picture, the numbers of text_input called Product Code i depends on the value from the number_input called Number of Products. So if there are x number of products, there will be x number of text_input generated dynamically. Moreover, the value inside the generated text_input can be extracted as well.

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

答案1

得分: 1

这是一种方法来实现这一点。
首先,使用列表推导来存储键(用于以后从text_input中提取值的变量)和值(text_input)。
接下来,使用键和值来设置类中的属性。
可以使用类内的属性来提取标记为product2的text_input中的值,例如使用p.product2

import streamlit as st

number_of_products = st.sidebar.number_input(label="产品数量",
                                     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"产品代码 {x+1}", value=0) for x in range(number_of_products)]

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

# 每个键的值都存储在类中作为属性
st.write(p.product2)

使用字典和exec命令也可以动态声明变量,但当text_input中的值不是数字时,将会生成错误。

英文:

Here is one way to do this.
First, use list comprehension to store keys (variables to use to extract values from text_input later) and values (text_input).
Next, use key and value to set the attribute in a class.
The value from text_input labelled as product2 can be extracted using the attribute within the class using p.product2 for example.

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)

Using dictionary and exec command can also dynamically declare variables, but when the value inside the text_input is not a number, it will generate an error.

答案2

得分: 0

生成动态输入小部件内容在使用Streamlit的会话状态时是可能的。然而,Streamlit在输入小部件交互时可能会刷新页面,这是一个潜在的缺点。

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

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

import streamlit as st

with st.form("产品数量"):
  numProducts = st.number_input('插入一个数字', key='numProducts')
  submitForm = st.form_submit_button("设置产品数量")

  if submitForm:
    st.success("请在下方分配产品代码")

if 'numProducts' in st.session_state.keys():
  with st.form("产品代码"):
    for i in range(st.session_state['numProducts']):
      # 在这里插入带有键的文本输入

希望对您有所帮助!

英文:

Generating dynamic input widget content is possible when using streamlit's session state. However, there is a potential drawback of streamlit refreshing the page upon input widget interaction.

One way to solve for this is to create multiple forms. For example, in your case you can create one form for "Number of Products", and update this value to the session state.

Next, you can create another form that takes in this "Number of Products" parameter and creates x number of input widgets.

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

Hope this helps!

huangapple
  • 本文由 发表于 2023年2月8日 17:31:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/75383700.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定