Trying to alter a empty widget in a function has no effect

The Problem
I’m trying to sync up two number_input() widgets to where the value of one is the others value multiplied or divided by a specified by a value. I’ve tried implementing this by creating two empty widgets, turning them into number inputs, and then using the on_change parameter, I execute a a function that updates the other widget with the correct information.

Expected Result
The idea is that it should update the empty widget with a new num input widget after you change the value in the other input widget.

Actual Result
Nothing changes. I added print statements in the functions in order to check that the actual function was running, and I can confirm that the function is getting called without an error. However the line that alters the widget seems to do nothing. It only seems to alter the widget if I do it outside of a function. I tested this by setting up the num input widget, sleeping for 5 seconds and then changing it to a text widget.

My Code

    #Initialize empty widgets
    epochPos = st.sidebar.empty()
    timeInPos = st.sidebar.empty()

    epoch = 50
    timeIn = (float(50) / modelEpm)

    def updateEpoch(widgetIn):
      newValue = int(round(timeIn * modelEpm))
      print(newValue)
      epoch = widgetIn.number_input('Epochs*', min_value=0, value=newValue, step=10, on_change=updateHours, args=[timeInPos])
      
    def updateHours(widgetIn):
      newValue = (float(epoch) / modelEpm)
      print(newValue)
      timeIn = widgetIn.number_input('Hours*', min_value=0.0, value=newValue, step=0.25, on_change=updateEpoch, args=[epochPos])

    epoch = epochPos.number_input('Epochs', min_value=0, value=50, step=10, on_change=updateHours, args=[timeInPos])
    timeIn = timeInPos.number_input('Hours', min_value=0.0, value=(float(50) / modelEpm), step=0.25, on_change=updateEpoch, args=[epochPos])

Please let me know if you need any more information about my project. All help is appreciated, and thanks in advance.

I’m trying to sync up two number_input() widgets to where the value of one is the others value multiplied or divided by a specified by a value.

Hi @pbpbpb12, welcome to the Streamlit community!! :wave: :partying_face:

Here are two approaches to the problem using Session State and Callbacks:

import streamlit as st
import numpy as np

newValue = 2
num1 = st.number_input("num1", 0, value=50, step=10, key="num1")
num2 = st.number_input("num2", 0., value=st.session_state.num1/newValue, key="num2")

# -------------------------------------
def updateNum4():
    newValue = np.random.randint(1, 10, size=1)
    st.session_state.num4 = st.session_state.num3 / newValue

num3 = st.number_input("num3", 0, value=50, step=10, key="num3", on_change=updateNum4)
num4 = st.number_input("num4", min_value=0, step=10, key="num4")

numinput-sync

Does this help?

Happy Streamlit’ing! :balloon:
Snehan

Thanks for the help with the session states. That makes a lot of sense now.

1 Like