I’m writing a motion detection / object recognition demo on top of Streamlit and OpenCV. The demo is completely local, so I might as well use a widget toolkit like Tkinter or PyQt, but using Streamlit seems simpler. I can emulate streaming video on the main page of the app with something like this:
# main.py
with st.empty():
while True:
grabbed, frame = stream.read()
if grabbed:
st.image(frame, channels="BGR")
But what I actually want to do is to have the main page fetch and process the frames, then have them render on a subpage, like this:
# main.py
view = st.Page("view.py")
app = st.navigation([view])
app.run()
while True:
grabbed, frame = stream.read()
if grabbed:
process(frame)
# view.py
with st.empty():
st.image(frame, channels="BGR")
I can pass the frame between the pages using a session variable, but the second page doesn’t update while the loop in the first page is running, even if enclose the code in a function decorated with @st.fragment. Any ideas on how to do this, other than to move the rendering code back into the loop?
Edit: added st.navigation to show relation between pages.
Two page scripts will not run concurrently for a single user. For each user viewing your app, only the page they are on is running (or finished running and waiting for the next action). What are you trying to accomplish by running something on a page that a user isn’t viewing?
I’ve edited the message to clarify my use case: the main page includes calls to st.page and st.navigation that set up the second page as a subpage of the first. The ST docs suggest this works almost like template inclusion - where one template sets up the overall look of the website, and another formats the main content. What I’m trying to do is to have the main page run all of the code that is shared between subpages - including the OpenCV loop - and have one of those subpages display the output in real time. The problem is, that subpage only gets to run once before the loop starts, and then nothing else gets updated until it finishes. In a “regular” async context I could call asyncio.sleep(0) inside the loop to force a thread switch and allow the subpage to refresh; but ST has its own control flow, so I don’t think it’ll work here.
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.