Streamlit 項目知識點總結

目錄

1. 單選框、下拉框格式化

2. 多媒體資源的引用

2.1 搭建一個簡易的http服務器

2.2 約定多媒體資源的輸入格式

2.3 解析多媒體資源

3. 設置頁面的全局背景圖片

4. 輸出流式文本(類似打字效果)

4.1 使用內置的 st.write_stream 方法實現

4.2 使用內置的 st.write 方法實現

5. 分頁導航

6. 使用模板渲染頁面

7. 多頁面方案

7.1 創建一個導航文件

7.2 定義每個頁面的內容

7.3 渲染導航


????????

????????最近使用python的streamlit庫做了個簡單的小項目,過程中碰到了不少問題,現總結如下。

1. 單選框、下拉框格式化

????????默認情況下,單選框和下拉框的標簽文本就是 options 參數中的列表數據,但在大多數的實際應用場景下,我們不僅需要在頁面上顯示標簽文本,同時還需要傳遞它們對應的id索引,這個時候,我們就需要對單選框和下拉框的標簽進行格式化處理。以下是單選框格式化的示例代碼:

# 使用id字段作為索引
option_list = [data.id for data in data_list]
# 使用title字段作為標簽文本
label_list = [data.title for data in data_list]
note_id = st.sidebar.radio('', option_list, format_func=lambda item: label_list[option_list.index(item)], label_visibility='collapsed')
if note_id:# 將id參數傳遞給其他業務邏輯

????????提示:該種方式同樣適用于下拉框的數據處理。

2. 多媒體資源的引用

????????streamlit中有內置的方法可以顯示圖片、音頻和視頻等多媒體資源,但請注意,這些方法都是獨立的,無法同時輸出圖片和音視頻混合的富文本信息。假如現在有一段文本需要輸出,這段文本中不僅包含了文字,同時還包含了圖片、音視頻等信息,對于這樣的場景需求,streamlit中的st.html()方法似乎可以實現,但還不夠完美,因為st.html()方法對多媒體資源的引用格式,通常都是http(s)協議的url路徑,所以如果能有一個http文件服務器,將streamlit應用中的本地資源,映射成為http資源,那就能完美解決這樣的場景需求了。具體實施步驟如下:

2.1 搭建一個簡易的http服務器

????????基于python的http.server模塊,我們可快速搭建一個簡易的http服務器。

2.2 約定多媒體資源的輸入格式

????????在streamlit應用中,約定好多媒體資源的輸入格式,示例格式如下:

圖片格式:![圖片描述][圖片地址],圖片描述可以為空
音頻格式:![audio][音頻地址],audio為固定關鍵詞
視頻格式:![video][視頻地址],video為固定關鍵詞
2.3 解析多媒體資源

????????根據約定好的格式,將多媒體資源解析出來,并映射到http文件資源,如下:

import re
import streamlit as stcontent = "我是一段包含了文字、圖片和音視頻的富文本"# 替換圖片,其中st.secrets.httpd.serverUrl是應用中配置的http文件服務器地址
image_pattern = r'!\[(.*)\]\[(.*?)\]'
placeholder = r'<div><img src="{}\2" alt="\1" title="\1" style="max-width: 100%; border-radius: 5px;"/></div>'.format(st.secrets.httpd.serverUrl)
content = re.sub(image_pattern, placeholder, content)# 替換音頻
audio_pattern = r'!\[audio\]\[(.*?)\]'
placeholder = r'<div><audio src="{}\1" style="max-width: 100%; border-radius: 5px;" controls>您的瀏覽器不支持該元素</audio></div>'.format(st.secrets.httpd.serverUrl)
content = re.sub(audio_pattern, placeholder, content)# 替換視頻
video_pattern = r'!\[video\]\[(.*?)\]'
placeholder = r'<div><video src="{}\1" style="max-width: 100%; border-radius: 5px;" controls>您的瀏覽器不支持該元素</video></div>'.format(st.secrets.httpd.serverUrl)
content = re.sub(video_pattern, placeholder, content)# 最后輸出
st.html(content)

3. 設置頁面的全局背景圖片

????????背景圖片可以是本地文件,也可以是http網絡圖片,如果是本地圖片,必須將它轉換為base64字符串,否則無法正常顯示。

????????核心代碼就一條語句,如下:

import streamlit as stst.html(f'''<style>.stApp:before{{background: url({background_image}) no-repeat fixed;background-size: cover;z-index: 1000000;pointer-events: none;position: absolute;width: 100%;height: 100%;content: "";opacity: 0.2;}}</style> 
''')

????????其中的background_image是我們需要傳遞的參數,參數值就是我們前面提到的,要么是http圖片路徑,要么是圖片的base64編碼字符串。

????????下面附一個圖片轉base64字符串的方法:

import base64
import streamlit as stimage_path = '本地圖片路徑'
with open(image_path, 'rb') as file:encoded_string = base64.b64encode(file.read())
data = encoded_string.decode('utf-8')
background_image = 'data:image/png;base64,{}'.format(data)

4. 輸出流式文本(類似打字效果)

4.1 使用內置的 st.write_stream 方法實現
import time
import streamlit as st# 將字符串轉換為字符生成器
def split_text(string):for char in string:yield chartime.sleep(0.1)# 建議將輸出文本放在三個引號內,以保持原有格式
text = '''想和你說,今天的云和你,都十分可愛。\n我把喜歡寫進風里,從此整個世界都是你。
'''st.write_stream(split_text(text))
4.2 使用內置的 st.write 方法實現

????????st.write 方法更加靈活,可以根據需要定制我們任何想要的輸出。先封裝一個工具類,如下:

import time
import streamlit as stclass StreamlitUtil():'''將字符串轉換為字符生成器@string: 字符串'''@staticmethoddef split_text(string):for char in string:yield chartime.sleep(0.1)'''輸出流式字符串(類似打字效果)@obj: 字符串、字符串列表或者字符串生成器@container: 容器對象,默認為st,也可以是其它值,如:st.sidebar等。'''@staticmethoddef write_stream(obj, container=st):if isinstance(obj, str):container.write(StreamlitUtil.split_text(obj))returnif isinstance(obj, list):for item in obj:container.write(StreamlitUtil.split_text(item))returncontainer.write(obj)'''輸出流式聊天信息(類似打字效果)@message_list: 聊天信息列表,格式 [{'用戶名稱1': '內容1'}, {'用戶名稱2': '內容2'} ...]'''@staticmethoddef write_stream_chat(message_list):for message_dict in message_list:# 注意:popitem()方法會移除最后插入的鍵值對name, message  = message_dict.popitem()st.chat_message(name).write(StreamlitUtil.split_text(message))

????????構造數據并調用:

from streamlit_util import StreamlitUtil as sudef run():text = '想和你說,今天的云和你,都十分可愛。'# 構造字符串列表并以流式輸出string_list = []for index in range(3):string_list.append(f'{index+1}: {text}')su.write_stream(string_list)# 構造聊天信息列表并以流式輸出string_list = []for index in range(3):string_list.append({'user': f'{index+1}: {text}'})su.write_stream_chat(string_list)run()

5. 分頁導航

????????分頁導航在web應用中是一個非常常見的功能,當有大量數據需要在頁面上渲染時,考慮到瀏覽器頁面的承受能力和后臺服務器的壓力,通常會對數據作分頁處理。

????????注意:此處只介紹如何實現分頁導航的功能,不討論分頁的數據如何獲取。

????????一個完整的分頁導航主要包含兩個部分:分頁按鈕和按鈕事件。

????????先來看下如何渲染一個分頁導航:

'''
顯示分頁導航欄
@container: 容器對象,即分頁導航欄顯示在什么地方
@total_page: 總頁數
'''
def show_page_nav(container, total_page=1):if total_page < 1:total_page = 1page_nav = {'first_page': '首頁','prev_page': '上頁','next_page': '下頁','last_page': '尾頁'}index = 0cols = container.columns(len(page_nav))for key in page_nav:with cols[index]:st.button(page_nav[key], on_click=change_page_state, args=(key, total_page))index += 1current_page = su.get_session('current_page', 1)container.caption('#### 第 {} 頁 / 共 {} 頁'.format(current_page, total_page))

????????show_page_nav 函數中,我們定義了分頁導航中包含了哪些按鈕,并從session中獲取了當前狀態是第幾頁。同時我們還注意到,在定義分頁按鈕的時候,我們綁定了一個單擊事件函數,這個函數的作用就是保存當前狀態的頁碼,它的具體內容如下:

'''
分頁按鈕的業務邏輯處理,通過session來存儲當前頁信息
@page_button_name: 分頁按鈕名稱
@total_page: 總頁數
'''
def change_page_state(page_button_name, total_page):if page_button_name == 'first_page':su.set_session('current_page', 1)returnif page_button_name == 'prev_page':current_page = su.get_session('current_page', 1)if current_page > 1:su.set_session('current_page', current_page - 1)else:su.set_session('current_page', 1)returnif page_button_name == 'next_page':current_page = su.get_session('current_page', 1)if current_page >= total_page:su.set_session('current_page', total_page)else:su.set_session('current_page', current_page + 1)returnif page_button_name == 'last_page':su.set_session('current_page', total_page)return

????????change_page_state 函數中,我們針對每個按鈕的單擊事件分別進行了處理,處理的最終目的是為了確認當前狀態的頁碼,并將這個頁碼存儲在session中。

????????我們發現,以上代碼只是渲染了一個分頁導航欄,并將按鈕點擊時的當前頁碼保存在了session中,似乎并沒有關聯其它具體的業務邏輯,那么如何將它整合到具體的業務邏輯中呢?其實,關鍵就在于session,通過session我們可以共享數據,這就意味著,在具體的業務邏輯中,我們只需要將當前頁碼作為參數傳遞給獲取數據的函數即可。

6. 使用模板渲染頁面

????????我們知道,streamlit中內置了各種輸出函數,可以將我們想要展示的內容渲染到頁面上,其中,有一個st.html()函數,為我們渲染豐富多彩的頁面提供了無限可能。

????????試想下,如果要渲染一段樣式豐富的文本,我們會怎么做呢?最容易想到的就是直接在python代碼中定義好樣式和內容,并將他們通過st.html()函數進行輸出。這樣做,從功能實現上來說沒問題,但由于我們將樣式和內容混在了一起,尤其當樣式很多的時候,對于代碼的后期維護將會是一個災難。這個時候,你可能就會想,那如果將樣式和內容分離呢?好注意,那么就讓我們來看下,如何實現樣式和內容的分離。

????????首先,定義一個html文件模板,示例內容如下:

<div style="text-align: center;"><div style="font-weight: bold;">{title}</div><div style="color: #999999;">{publish_time}</div>
</div>
<div style="margin-top: 10px;">{content}
</div>

????????我們看到,模板文件中,除了html標簽和樣式,我們還定義了幾個變量,這些變量用花括號引起來,我們姑且稱它們為占位符。

????????下面,我們再來看下如何引用這個模板,并使用其中的占位符:

# 定義模板文件路徑
template = 'page/template/content.html'
# 讀取模板文件內容,并替換其中的占位符變量
with open(template, 'r') as file:content = file.read()content = content.replace('{title}', '厲害了我的國')content = content.replace('{publish_time}', '2024-05-31')content = content.replace('{content}', '這里是一大段內容...')# 輸出內容到頁面st.html(content)

????????怎么樣?這樣的代碼看起來是不是很清爽干凈,后期的維護也會簡單輕松很多。

7. 多頁面方案

????????從1.36.0版本開始,streamlit 啟用了新的多頁面方案,使用起來更加簡單、靈活。

????????導航的定義建議使用字典格式,如下:

pages = {'一級導航1' : [st.Page('py文件路徑', title='📘 二級導航1', url_path='url路徑,用于顯示在地址欄中', default=True),st.Page('py文件路徑', title='📋? 二級導航2', url_path='url路徑,用于顯示在地址欄中', default=False)],'一級導航2' : [st.Page('py文件路徑', title='🃏 二級導航3', url_path='url路徑,用于顯示在地址欄中', default=False),st.Page('py文件路徑', title='🎁 二級導航4', url_path='url路徑,用于顯示在地址欄中', default=False)]
}

????????屬性說明:

????????第一個參數:導航頁面對應的py文件路徑,建議使用相對路徑。

????????title:二級導航的名稱。

????????url_path:導航的url路徑,用于顯示在瀏覽器的地址欄中,如果未定義該參數,則默認使用py文件名稱(去除.py后綴)作為url路徑。

????????default:是否作為應用的默認頁面,默認為 False,默認情況下,取 st.navigation 方法參數中的第一個頁面作為應用的首頁。

????????下面來演示一個簡單的多頁面應用。

7.1 創建一個導航文件

????????創建一個 router.py 文件,項目中所有的導航頁面都存放在這個文件中,內容如下:

import streamlit as stdef load_router():pages = {'🏠? 導航名稱1' : [st.Page('pages/front/測試1.py', title='📘 子導航1'),st.Page('pages/front/測試2.py', title='📋? 子導航2')],'?? 導航名稱2' : [st.Page('pages/admin/測試3.py', title='🃏 子導航3'),st.Page('pages/admin/測試4.py', title='🎁 子導航4')]}return pages
7.2 定義每個頁面的內容

????????以 測試1.py 文件為例,它的內容如下:

import streamlit as stdef run():st.write('欲買桂花同載酒')run()
7.3 渲染導航
import streamlit as st
import router as navdef run():st.set_page_config(layout='wide', page_title='導航示例')pg = st.navigation(nav.load_router())pg.run()run()

????????效果如下:

?????????如有疑問,可以關注 我的知識庫,直接提問即可。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/82455.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/82455.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/82455.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

maven模塊化開發

使用方法 將項目安裝到本地倉庫 mvn install 的作用 運行 mvn install 時&#xff0c;Maven 會執行項目的整個構建生命周期&#xff08;包括 compile、test、package 等階段&#xff09;&#xff0c;最終將構建的 artifact 安裝到本地倉庫&#xff08;默認路徑為 ~/.m2/repos…

(11)Service Mesh架構下Java應用實現零信任安全模型

Service Mesh架構下Java應用實現零信任安全模型 ?? TL;DR: 本文詳細介紹如何在Service Mesh架構中實現零信任安全模型,包括身份認證、授權控制、加密通信和持續監控四大核心技術,以及與Istio、Envoy等組件的集成方案。 目錄 零信任安全模型概述關鍵技術實現最佳實踐Service…

修改 K8S Service 資源類型 NodePort 的端口范圍

在 Kubernetes 中&#xff0c;Service 類型為 NodePort 時&#xff0c;默認分配的端口范圍為 30000~32767。如果你希望使用自定義端口&#xff08;如 8080、8888 等&#xff09;&#xff0c;就需要修改 kube-apiserver 的默認配置。 本文將詳細介紹如何修改 Kubernetes 中 Nod…

MySQL 可觀測性最佳實踐

MySQL 簡介 MySQL 是一個廣泛使用的開源關系型數據庫管理系統&#xff08;RDBMS&#xff09;&#xff0c;以其高性能、可靠性和易用性而聞名&#xff0c;適用于各種規模的應用&#xff0c;從小型網站到大型企業級系統。 監控 MySQL 指標是維護數據庫健康、優化性能和確保數據…

CentOS安裝最新Elasticsearch8支持向量數據庫

大家都知道Elasticsearch是支持向量的存儲和查詢的&#xff0c;今天我們來介紹下如何安裝支持向量數據庫的Elasticsearch &#xff0c; 操作環境是CentOS。 成功安裝截圖 大家進入系統shell&#xff0c;跟我執行下面命令進行安裝。 更新系統 [rootlocalhost ~]# sudo yum u…

SDL2常用函數SDL事件處理:SDL_Event|SDL_PollEvent

SDL_Event SDL_Event是個聯合體&#xff0c;是SDL中所有事件處理的核心。 SDL_Event是SDL中使用的所有事件結構的并集。 只要知道了那個事件類型對應SDL_Event結構的那個成員&#xff0c;使用它是一個簡單的事情。 下表羅列了所有SDL_Event的所有成員和對應類型。 Uint32typ…

webpack吐環境分析

需要解決的問題 扣取下來的webpack文件過大 解決思路 用ast將需要的代碼扣下來 結果展示 實現步驟 第一步&#xff1a;我們得知道需要哪些模塊 在入口處&#xff0c;增加模塊記錄 第二步&#xff0c;分析ast代碼 通過分析發現,key 有三種值 分別為NumbericLiteral、StringLi…

微軟語音合成助手資源下載

微軟語音合成助手資源下載 【下載地址】微軟語音合成助手資源下載 微軟語音合成助手是一款基于先進AI技術的文本轉語音工具&#xff0c;能夠將文字內容快速轉換為自然流暢的語音。它支持高度自定義的語音參數&#xff0c;包括語速、音調、發音和停頓等&#xff0c;滿足多樣化需…

青少年編程與數學 02-020 C#程序設計基礎 01課題、C#編程概要

青少年編程與數學 02-020 C#程序設計基礎 01課題、C#編程概要 一、微軟.NET開發平臺1. 核心組件2. 特點3. 應用場景4. 開源與社區5. 版本與更新6. 學習資源 二、C# 編程語言1. 歷史背景2. 語言特性&#xff08;1&#xff09;面向對象&#xff08;2&#xff09;類型安全&#xf…

圖片文件未正確加載?—— Webpack 無法正確解析圖片,生成了一個空的 Base64 URL

如果你打印出的圖片 URL 是 data:image/png;base64, 后面沒有實際的 Base64 數據&#xff0c;可能有以下幾種原因&#xff1a; ??1. 圖片文件未正確加載?? ??可能原因??&#xff1a;圖片路徑錯誤&#xff0c;導致 Webpack 無法正確解析圖片&#xff0c;生成了一個空的…

3D打印仿造+ AI大腦賦能,造出會思考的全景相機

在自然界的生存競賽里&#xff0c;節肢動物堪稱視覺界的 "卷王"&#xff01;那些長著復眼的小機靈鬼&#xff0c;比如蜜蜂、蜻蜓&#xff0c;別看個頭小&#xff0c;視覺能力卻超強。 現在&#xff0c;科學家把它們的眼睛 " 偷"過來啦 —— 不是真偷&…

rabbitmq單機多實例部署

RabbitMQ 單實例部署 單實例部署是指在一臺服務器上運行一個 RabbitMQ 實例。這種部署方式適用于小型應用或開發環境,配置簡單,資源占用較少。單實例部署的核心是安裝 RabbitMQ 并啟動服務,通常需要配置 Erlang 環境,因為 RabbitMQ 是基于 Erlang 編寫的。單實例部署的優勢…

知識宇宙-職業篇:后端工程師

名人說&#xff1a;博觀而約取&#xff0c;厚積而薄發。——蘇軾《稼說送張琥》 創作者&#xff1a;Code_流蘇(CSDN)&#xff08;一個喜歡古詩詞和編程的Coder&#x1f60a;&#xff09; 目錄 一、后端工程師的定義與職責1. 什么是后端工程師&#xff1f;2. 主要工作職責 二、…

機試 | vector/array Minimum Glutton C++

題目地址 &#xff1a; C - Minimum Glutton #include<stdio.h> #include<iostream> #include<vector> #include<algorithm> using namespace std; int main() {//N:菜肴數&#xff0c;X&#xff1a;總甜度閾值&#xff0c;Y&#xff1a;總咸度閾值int…

【Django ORM】三萬字了解Django ORM的基本概念和基本使用

第一章 Django ORM 概述 1.1 什么是Django ORM 1.1.1 ORM的基本概念 ORM 即對象關系映射&#xff08;Object Relational Mapping&#xff09;&#xff0c;它是一種編程技術&#xff0c;用于在面向對象編程語言&#xff08;如 Python&#xff09;和關系型數據庫&#xff08;如…

在springboot項目中是否可以使用兩個不同地址的redis

在Spring Boot項目中可以通過多數據源配置的方式使用兩個不同地址的Redis實例。以下是具體實現方案 1.依賴配置 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><exclusio…

JMeter 教程:監控性能指標 - 第三方插件安裝(PerfMon)

目錄 【簡單介紹】 ? PerfMon 插件是什么&#xff1f; &#x1f6e0;? 安裝 PerfMon 插件 方法一&#xff1a;使用 JMeterPluginsManager 安裝&#xff08;推薦&#xff09; &#x1f50c; 安裝完成后組件介紹 &#x1f310; 服務端安裝 ServerAgent&#xff08;用于被…

【后端高階面經:數據庫篇】19、分庫分表查詢困境:無分庫分表鍵時的高效應對

一、分庫分表下的無分片鍵查詢困境 在分布式數據庫架構中,分庫分表通過分片鍵(如買家ID)將數據分散存儲,顯著提升了單表性能和系統擴展性。然而,當業務需要從非分片鍵維度(如賣家ID)進行查詢時,傳統架構暴露出以下核心問題: 1.1 跨分片掃描的性能災難 數據分散性:以…

ARM架構

目錄 哈佛結構 arm指令格式 有符號數的溢出&#xff08;8bit)? 無符號數的進位/借位 CPSR&#xff08;當前程序狀態寄存器&#xff09; ARM模式 arm異常類型 ARMv7架構異常向量表 arm異常的處理流程 arm寄存器 堆棧指針寄存器 arm模式切換流程 LDR指令、STR指令 指…

canvas(三)-動畫3d

在 <canvas> 中實現 3D 動畫通常需要借助 WebGL 技術,因為原生的 2D 上下文(CanvasRenderingContext2D)無法直接支持 3D 渲染。WebGL 是基于 OpenGL ES 2.0 的 JavaScript API,可以直接在瀏覽器中實現高性能的 3D 圖形渲染。以下是關于 <canvas> 3D 動畫的概念…