How to dynamically update a text in a text box?

Hello,
I would like to create a logging text box on a fixed position on the screen, but which I can dynamically update. The idea is the following:

#import streamlit as st

logging_textbox = st.empty()
logging_textbox.text_area("Logging: ", ‘–’, height=500)

And in this logging_textbox I would like to add text over time (and not just override the existing text).

For example, I would like to dynamically update a counter in this text box like the example below where I used the ‘write’ function:

  • counting at the same line till a certain number has been reached and then go to the next line and do the same

t = st,empty()
end_of_loop = False
counter = 1

while (end_of_loop==False):

t.write('Counter: ’ + str(counter))
if (counter % 10 ==0) :

t = st.empty()
t.write(‘the next line’)
t = st.empty()

counter += 1
if (counter > 100) :

end_of_loop = True

time.sleep(0.5)

Could anyone help me with this?

Thank you in advance.

Hi @Richard_SL, welcome to the Streamlit community!! :tada: :star_struck: :tada:

One of our community members, @BugzTheBunny, has created an amazing working example of a logging app. While it may not be exactly what you’re looking for, do you reckon you could repurpose the code to build your logging text box?

I’m still having a bit of trouble picturing exactly what you want to create. It would be great if you could break it down more or elaborate if @BugzTheBunny’s example isn’t what you have in mind?

Best, :balloon:
Snehan

1 Like

Hello @snehankekre , thank you very much for your fast reply. The example is indeed an interesting approach, however I would like to create it in a bit different way (unfortunately I am also still in a learning curve regarding Python and Streamlit).
The advantage of the example (code) is that you will always see the last lines of the text, the disadvantage is that the text box is growing, when more text is added (I would like to have a fixed size with scroll bars). I don’t know if that can be added…

The general idea is to create a fixed size “text box” on a webpage:

import streamlit as st
import time

st.set_page_config(layout="wide")
st.title('Logging in Text Box')

# creating a placeholder for the fixed sized textbox
logtxtbox = st.empty()
logtxt = 'start'
logtxtbox.text_area("Logging: ",logtxt, height = 500)

end_of_loop = False
counter = 1

while (end_of_loop==False):

    logtxt += 'Counter [' + str(counter) + '] \n'
    logtxtbox.text_area("Logging: ", logtxt, height=500)

    counter += 1
    if (counter > 100):
        end_of_loop = True

    time.sleep(0.2)

In this example the text box will stay fixed, however you will only see the first lines of the logging. Of course you can scroll to the end, but I would prefer to see the last added lines and be able to scroll back to the beginning (like for example a text editor where you scroll down till the end of the document).

An extra feature, as a next step, would be to also have the possibility to be able to override the text on the last line (for example a counter which is counting on the same line…
An example of that I made here below (but the combination is still another issue…):

import streamlit as st
import time

t = st.empty()
end_of_loop = False 
counter = 1

while (end_of_loop==False):
    t.write('Counter: ' + str(counter))
    if (counter % 10 ==0) :
        t = st.empty()

    counter += 1
    if (counter > 100) :
        end_of_loop = True

    time.sleep(0.2)

And in the end I would like to be able to get the complete content of this text box and write it to a text file.

If I find a solution in the meantime I will post it here, but all help is still very welcome.

It appears that this is possible with Dash: Set max height to a Div and make the content vertically scrollable - #5 by tcbegley - Dash Python - Plotly Community Forum.

1 Like

Two Dynamic Updates With Cautions

The placeholder code in the while loop is likely not needed. Using st.write or st.markdown would likely work fine. I just wanted to show that IF you use this while look approach, put it at the end of your streamlit script. Even then, watch how the time is interrupted when the button state is updated in the code above the while loop. Thus, you can update later due to another later operation OR update continuously. Just put the continuous update (eternal while loop) stuff at the end.

import streamlit as st
from datetime import datetime
import time


# Section 1
button = st.button('Button')
button_placeholder = st.empty()
button_placeholder.write(f'button = {button}')
time.sleep(2)
button = False
button_placeholder.write(f'button = {button}')

# Section 2
time_placeholder = st.empty()

while True:
    timenow = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    time_placeholder.write(timenow)
    time.sleep(1)
1 Like

Hi Richard,

Your code helps me a lot.

Now I have the same question as you, is now possible to see the last line of the logging? Any new solution?

Best,

Junjie

If you came to this post to see how to update text dynamically, see if this discussion helps.