I like to find an example in which st.empty() is used within tabs. The application is as follows:
a) assume a file is changed on disk
b) one of the tabs includes a Preview container
c) the app runs automatically and once it finds the file gets changed the contents is displayed and the old contents is overwitten
e) I am using that with images that I read remotely from a camera
Steps to reproduce
I do not have a working example. It would be great to have such an example. What I tried did not work and when using the code I have (which is large) it repeats the image multiple times.
when I change look to while True: Expected behavior:
right now I only enable a one time update on button click, but I like to change that to update whenever the preview image is changed.
Actual behavior:
Explain the undesired behavior or error you see when you run the code above.
If you’re seeing an error message, share the full contents of the error message here.
I’m not sure it would be easy to do this entirely in streamlit, but here’s a convoluted way to accomplish it, using the watchdog library.
streamlit_app.py
from datetime import datetime
import streamlit as st
st.write("Last time this page ran:", datetime.now())
watching.py
import time
from datetime import datetime
from pathlib import Path
from watchdog.events import FileSystemEventHandler
from watchdog.observers import Observer
class MonitorFolder(FileSystemEventHandler):
def on_modified(self, event):
print(event.src_path, event.event_type)
current_time = datetime.now()
contents = Path(".streamlit/secrets.toml").read_text()
# Replace last_run = "<previous datetime>" with new datetime
current_lines = contents.splitlines()
for i, line in enumerate(current_lines):
if line.startswith("last_run"):
current_lines[i] = f"last_run = '{current_time}'"
contents = "\n".join(current_lines)
Path(".streamlit/secrets.toml").write_text(contents)
print(contents)
if __name__ == "__main__":
file_path = "dir_to_watch" # UPDATE this to the directory of the file you expect to be changing
event_handler = MonitorFolder()
observer = Observer()
observer.schedule(event_handler, path=file_path, recursive=True)
print("Monitoring started")
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
Steps to get it working:
Add a line to .streamlit/secrets.toml which is last_run = ''
Update the watcher.py with the directory you want to watch
Run the streamlit app with streamlit run streamlit_app.py
In a separate process, run python watching.py
Whenever something in the directory_to_watch folder changes, watchdog will then update the secrets.toml with a new value. I happen to know that if you update that file, your streamit app will automatically rerun, even if it’s not using that value.
Quite convoluted, but hopefully that works for you, or at least gives you some ideas.
yes its a good idea to do this with watchdog. But my setup is actually much easier, I can just poll for the image from the camera in a loop in the application. The actual issue I have is that for some reason I can not get st.empty() do work so that the image is not appended every time in a tab that contains a container.
I am sure that I likely do not know how to uses the empty in relationship to a tab or a container.
so I have something like
tab_preview, tab_general, tab_focusbracketing = \
st.tabs(["Preview", "Settings", "Focusbraceting"])
def preview(position=tab_preview):
camera = CCAPI()
device = camera.get_deviceinformation()
name = "./preview.jpeg"
r = camera.liveview(display="on", size="medium")
r = camera.get_liveview_image(name)
c = position.empty()
while True:
try:
c = position.empty()
c = position.container()
position.markdown("# Preview")
image = Image.open('./preview.jpeg')
position.image(image, caption='Preview')
position.session_state.image_available = True
except Exception as e:
position.write("error loading preview")
position.write(e)
print("preview")
st.sidebar.button("Preview Image from :camera:", on_click=preview)
so for some reason the empty() does not empty the container, but just appends
Yes its a good idea to do this with watchdog, but I am lucky, I can just poll for the image. SO the real issue I have is with st.empty in a container within a tab
note i removed some more stuff, but left CCAPI in as this is my python library to interface with a canon camera
mport streamlit as st
from PIL import Image
import streamlit as st
import requests
from ccapi.ccapi import CCAPI
tab_preview, tab_general, tab_focusbracketing = \
st.tabs(["Preview", "Settings", "Focusbraceting"])
camera = CCAPI()
settings = camera.get_settings()
def preview(position=tab_preview):
camera = CCAPI()
device = camera.get_deviceinformation()
name = "./preview.jpeg"
# camera.release()
r = camera.liveview(display="on", size="medium")
r = camera.get_liveview_image(name)
# camera.preview(name)
position.markdown("# Preview")
while True:
try:
image = Image.open('./preview.jpeg')
position.image(image, caption='Preview')
position.session_state.image_available = True
except Exception as e:
position.write("error loading preview")
position.write(e)
print("preview")
st.sidebar.button("Preview Image from :camera:", on_click=preview)
So somehow I have to convert the code in the loop in some fashion so that an st.empty is used so that when I repeat the look it overwrites the image.
I also want to preserve that the tab is on top
I thought first I can do
while True:
area = position.empty()
area = position.container
area.markdown("# Preview")
image = Image.open('./preview.jpeg')
area.image(image, caption='Preview')
Ah, in that case, the fix isn’t too bad – just declare the area = position.empty() outside of the while loop, so it doesn’t get created over and over again.
Here’s a simplified version of the script that I think does what you want:
import time
import streamlit as st
from randimage import get_random_image
tab_preview, tab_general, tab_focusbracketing = st.tabs(
["Preview", "Settings", "Focusbraceting"]
)
position = tab_preview
area = position.empty()
while True:
with area.container():
st.markdown("# Preview")
image = get_random_image((128, 128))
st.image(image, caption="Preview")
time.sleep(1)
Thanks for stopping by! We use cookies to help us understand how you interact with our website.
By clicking “Accept all”, you consent to our use of cookies. For more information, please see our privacy policy.
Cookie settings
Strictly necessary cookies
These cookies are necessary for the website to function and cannot be switched off. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms.
Performance cookies
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us understand how visitors move around the site and which pages are most frequently visited.
Functional cookies
These cookies are used to record your choices and settings, maintain your preferences over time and recognize you when you return to our website. These cookies help us to personalize our content for you and remember your preferences.
Targeting cookies
These cookies may be deployed to our site by our advertising partners to build a profile of your interest and provide you with content that is relevant to you, including showing you relevant ads on other websites.