用streamlit实现云台控制界面
- 效果图
- PC上的效果
- 手机上的效果
- 源码:
本文演示了,如何用streamlit做一个云台控制界面。功能包括:用户登录,事件的处理,图片的更新
版本信息:
- streamlit_authenticator: 下载链接
- streamlit : 1.31.1
- python: 3.11
修改点:
- streamlit_authenticator 从bcrypt.hashpw改成hashlib.sha256(以提升速度)
效果图
PC上的效果
手机上的效果
源码:
import streamlit as st #1.31.1
import cv2
import numpy as np
import datetime
import glob
import os
import sys
sys.path.append(".")
import streamlit_authenticator as stauth
import yaml
from yaml.loader import SafeLoaderdef get_image(kwargs):'''生成图片,删除旧图片'''print(kwargs)image=np.ones((240,320,3),dtype=np.uint8)*128current_time = datetime.datetime.now()date_format ='%Y%m%d%H%M%S'time_string = current_time.strftime(date_format)for name in glob.glob("img_cache/*.png"):date_object = datetime.datetime.strptime(os.path.basename(name).split(".")[0], date_format)if (current_time-date_object).total_seconds()>60:os.remove(name)font = cv2.FONT_HERSHEY_SIMPLEX label=[time_string]for k,v in kwargs.items():if v:label.append(k)cv2.putText(image, "-".join(label), (1, 32), font, 0.6, (255, 255, 255),1, cv2.LINE_AA)ok, img = cv2.imencode('.png', image, [cv2.IMWRITE_JPEG_QUALITY,20])filename="img_cache/{}.png".format(time_string)with open(filename,"wb") as f:f.write(img.tobytes())return filenamedef mainContent(): '''主界面'''# 初始化状态if 'last_image' not in st.session_state:st.session_state['last_image'] = None# UI布局with st.container(border=True): st.write("云台控制")col1, col2,col3,col4 = st.columns([0.3,0.3,0.3,0.3])with col1:st.button(':arrow_up:',use_container_width=True,kwargs={'type':"up"},key="up_btn")with col2:st.button(':arrow_down:',use_container_width=True,kwargs={'type':"down"},key="down_btn") with col3:st.button(':arrow_left:',use_container_width=True,kwargs={'type':"left"},key="left_btn") with col4: st.button(':arrow_right:',use_container_width=True,kwargs={'type':"right"},key="right_btn") with st.container(border=True):st.write("预置点控制")preset = st.slider('预置点', 1, 10, 1)st.button('跳转到预置点',use_container_width=False,kwargs={'type':"down"},key="goto_btn") with st.container(border=True):st.write("预览")placeholder = st.empty()# 事件处理逻辑if st.session_state.up_btn or st.session_state.down_btn:with placeholder.container():st.session_state["last_image"]=get_image({"up_btn":st.session_state.up_btn,"down_btn":st.session_state.down_btn})if st.session_state.left_btn or st.session_state.right_btn:with placeholder.container():st.session_state["last_image"]=get_image({"left_btn":st.session_state.left_btn,"right_btn":st.session_state.right_btn})if st.session_state.goto_btn:with placeholder.container():st.session_state["last_image"]=get_image({"goto_btn":st.session_state.goto_btn,"preset":preset})if st.session_state["last_image"]:st.image(st.session_state["last_image"])if __name__ == "__main__":# 设置标题,图标等st.set_page_config(layout="centered",page_title="云台控制",page_icon=":shark:")# 设置自定义样式button_styles = {'width': '54px','-webkit-box-align': 'center','align-items': 'center','-webkit-box-pack': 'center','justify-content': 'center', 'display': 'flex','padding': '10px'}st.write('<style>div.row-widget.stButton{ %s }</style>' % button_styles, unsafe_allow_html=True)st.markdown('<style>section.css-vk3wp9.eczjsme11{display: none;}</style>', unsafe_allow_html=True)# 鉴权with open('config.yaml') as file:config = yaml.load(file, Loader=SafeLoader)authenticator = stauth.Authenticate(config['credentials'],config['cookie']['name'],config['cookie']['key'],config['cookie']['expiry_days'],config['preauthorized']) authenticator.login()if st.session_state["authentication_status"]:authenticator.logout()mainContent()elif st.session_state["authentication_status"] is False:st.error('用户名或密码错误')elif st.session_state["authentication_status"] is None:st.warning('请输入用户名和密码')