You can rely on the natural updating of the columns content when Streamlit reruns. If get_students()
is dynamic, then the columns will automatically adjust themselves. Here’s the extended example, with a dynamic student list and fake continuous update using time.sleep
and st.experimental_rerun
(you can use a button action to invoke the rerun instead of sleeping).
Code with continuous update
import streamlit as st
from dataclasses import dataclass
import time
import random
import numpy as np
state = st.session_state
if 'message' not in state:
state.message = 'No student enrolled'
st.info(state.message)
@dataclass
class Student():
def __init__(self, name, age, course):
self.name = name
self.age = age
self.course = course
def __repr__(self) -> str:
return f'|Name: {self.name}, Age: {self.age}, Course: {self.course}|'
def get_students():
num_students = random.randint(1,10)
print('', num_students)
rnd_ages = [random.randint(18,60) for _ in range(num_students)]
print('', rnd_ages)
rnd_course_stage = [c for c in np.random.permutation([100, 101, 200, 201, 300, 301, 400, 401, 500, 501])]
print('', rnd_course_stage)
rnd_course_subj = [c for c in np.random.permutation(['CS', 'DS', 'CS', 'DS', 'SS', 'CS', 'DS', 'CS', 'DS', 'SS'])]
print('', rnd_course_subj)
rnd_courses = [f'{sub}{stage}' for sub, stage in zip(rnd_course_subj, rnd_course_stage)]
print('', rnd_courses)
students = [Student(name=f'Student {i}', age=rnd_ages[i], course=rnd_courses[i]) for i in range(num_students)]
print(students)
return students
def _enroll_cb(student, index):
name = state[f'{student.name}_{index}']
age = state[f'{student.age}_{index}']
course = state[f'{student.course}_{index}']
state.message = f'Enrolled: {name}, {age}, {course}'
c1, c2, c3, c4 = st.columns([1,1,1,1])
c1.subheader('Student')
c2.subheader('Age')
c3.subheader('Course')
c4.subheader(' ')
for index, student in enumerate(get_students(), start=0):
with c1:
st.text_input('', student.name, key=f'{student.name}_{index}')
with c2:
st.number_input('', min_value=18, max_value=60, value=student.age, key=f'{student.age}_{index}')
with c3:
st.text_input('', student.course, key=f'{student.course}_{index}')
with c4:
st.write(' ')
st.button('enroll', on_click=_enroll_cb, args=(student,index), key= f'enroll_{index}')
time.sleep(3)
st.experimental_rerun()
![multi-column-widgets-with-continuous-update](https://global.discourse-cdn.com/streamlit/original/2X/b/b5005f7b49bc5cead03c4cceab6eaa1d29516de4.gif)
That’s all I have time to play around with, so hope you can take it forward from here.
Arvindra