pywebview的用途與特點
用途
pywebview
是一個輕量級Python庫,用于創建桌面應用程序(GUI)。它通過嵌入Web瀏覽器組件(如Windows的Edge/IE、macOS的WebKit、Linux的GTK WebKit),允許開發者使用HTML/CSS/JavaScript構建界面,并用Python處理后端邏輯。這種方式結合了Web技術的靈活性和Python的強大功能,適合快速開發跨平臺桌面應用。
特點
- 跨平臺支持:原生支持Windows、macOS、Linux,無需額外配置。
- 輕量級:無需完整的瀏覽器,僅依賴系統內置Web組件。
- 雙向通信:HTML前端與Python后端可互相調用函數。
- 簡單易用:API簡潔,學習成本低。
- 資源占用少:相比Electron等框架,內存占用更小。
基本使用方法
1. 安裝
pip install pywebview
2. 簡單示例(Python與HTML交互)
import webviewdef print_message(message):print(f"收到前端消息: {message}")# 創建一個HTML字符串作為界面
html = """
<!DOCTYPE html>
<html>
<head><title>PyWebView示例</title>
</head>
<body><button onclick="python.print_message('你好,Python!')">發送消息到Python</button><script>// 調用Python函數window.python = pywebview.api;</script>
</body>
</html>
"""# 創建窗口并加載HTML
window = webview.create_window("PyWebView應用", html=html)
webview.start(gui=None, debug=True) # gui=None自動選擇系統默認瀏覽器引擎
結合Flask與waitress開發應用
架構設計
- Flask:提供Web API,處理業務邏輯。
- pywebview:作為桌面應用的外殼,加載Flask的Web界面。
- waitress:在生產環境中替代Flask內置服務器,提供更好的性能。
開發環境代碼示例
# app.py - Flask后端
from flask import Flask, jsonifyapp = Flask(__name__)@app.route('/')
def index():return """<!DOCTYPE html><html><head><title>Flask + PyWebView應用</title></head><body><h1>Hello from Flask!</h1><button onclick="fetchData()">獲取數據</button><div id="result"></div><script>async function fetchData() {const response = await fetch('/api/data');const data = await response.json();document.getElementById('result').textContent = data.message;}</script></body></html>"""@app.route('/api/data')
def get_data():return jsonify({"message": "這是來自Flask后端的數據!"})if __name__ == '__main__':# 開發環境:使用Flask內置服務器app.run(debug=True, port=5000)
# desktop.py - PyWebView桌面應用包裝
import webview
import threading
import subprocessdef run_flask():# 啟動Flask應用(開發環境)subprocess.run(['python', 'app.py'])if __name__ == '__main__':# 在后臺線程中啟動Flaskflask_thread = threading.Thread(target=run_flask, daemon=True)flask_thread.start()# 創建PyWebView窗口,加載Flask應用window = webview.create_window("桌面應用", "http://localhost:5000")webview.start(gui=None, debug=True)
生產環境配置(使用waitress)
1. 修改Flask應用(app.py)
# app.py - Flask后端(生產環境)
from flask import Flask, jsonifyapp = Flask(__name__)@app.route('/')
def index():return """<!-- 同上,HTML內容 -->"""@app.route('/api/data')
def get_data():return jsonify({"message": "這是來自Flask后端的數據!"})# 移除開發環境的app.run(),改為導出app實例
2. 使用waitress啟動Flask
# server.py - 使用waitress啟動Flask(生產環境)
from waitress import serve
from app import appif __name__ == '__main__':serve(app, host='127.0.0.1', port=5000, threads=8) # 生產環境使用waitress
3. 修改PyWebView應用(desktop.py)
# desktop.py - PyWebView桌面應用(生產環境)
import webview
import threading
import subprocessdef run_flask():# 啟動Flask應用(生產環境使用waitress)subprocess.run(['python', 'server.py'])if __name__ == '__main__':# 在后臺線程中啟動Flaskflask_thread = threading.Thread(target=run_flask, daemon=True)flask_thread.start()# 創建PyWebView窗口,加載Flask應用window = webview.create_window("桌面應用", "http://localhost:5000")webview.start(gui=None, debug=False) # 生產環境關閉調試模式
打包應用的建議
為了將應用分發給最終用戶,可以使用PyInstaller
或cx_Freeze
將Python代碼打包成單個可執行文件:
# 使用PyInstaller打包
pyinstaller --onefile --windowed desktop.py
注意事項:
- 打包時需確保包含所有依賴項(如Flask、waitress、pywebview)。
- 在macOS/Linux上可能需要額外配置以確保WebView組件正確加載。
總結
通過結合pywebview
、Flask
和waitress
,可以開發出兼具美觀界面和強大功能的跨平臺桌面應用:
- 開發階段:使用Flask內置服務器和調試模式,提高開發效率。
- 生產階段:使用waitress替代Flask服務器,提升性能和穩定性。
- 部署階段:使用PyInstaller打包為獨立可執行文件,方便分發。
完整代碼
以下是在Windows平臺上結合PyWebView、Flask和Waitress的完整代碼實現。代碼分為三個主要文件,分別負責Flask后端、桌面應用包裝和生產環境啟動。
1. Flask后端代碼(app.py)
# app.py - Flask后端應用
from flask import Flask, jsonify, render_template_string
import osapp = Flask(__name__)# 確保中文正常顯示
app.config['JSON_AS_ASCII'] = False# 首頁路由
@app.route('/')
def index():return render_template_string("""<!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><title>PyWebView + Flask應用</title><style>body { font-family: 'Microsoft YaHei', sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }.container { background-color: #f9f9f9; border-radius: 8px; padding: 20px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); }h1 { color: #333; }button { background-color: #4CAF50; color: white; border: none; padding: 10px 20px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; margin: 4px 2px; cursor: pointer; border-radius: 4px; }#result { margin-top: 20px; padding: 10px; background-color: #e8f5e9; border-radius: 4px; }</style></head><body><div class="container"><h1>PyWebView + Flask桌面應用</h1><p>這是一個基于Web技術的跨平臺桌面應用示例。</p><button onclick="fetchData()">獲取數據</button><button onclick="callPythonFunction()">調用Python函數</button><div id="result">點擊按鈕查看結果...</div><script>// 從Python后端獲取數據async function fetchData() {try {const response = await fetch('/api/data');if (!response.ok) throw new Error('網絡響應失敗');const data = await response.json();document.getElementById('result').textContent = data.message;} catch (error) {document.getElementById('result').textContent = '錯誤: ' + error.message;}}// 調用Python函數(通過PyWebView的API)async function callPythonFunction() {try {// 確保PyWebView API已加載if (window.pywebview && window.pywebview.api) {const result = await window.pywebview.api.multiply_numbers(5, 3);document.getElementById('result').textContent = `Python計算結果: 5 × 3 = ${result}`;} else {document.getElementById('result').textContent = 'PyWebView API未加載';}} catch (error) {document.getElementById('result').textContent = '調用Python函數時出錯: ' + error.message;}}</script></div></body></html>""")# API路由 - 返回JSON數據
@app.route('/api/data')
def get_data():return jsonify({"message": "這是來自Flask后端的數據!","timestamp": str(os.times()),"platform": "Windows桌面應用"})# 導出Flask應用實例供其他模塊使用
if __name__ == '__main__':# 僅在直接運行此文件時使用Flask內置服務器(開發環境)app.run(debug=True, port=5000)
2. 開發環境啟動腳本(desktop_dev.py)
# desktop_dev.py - 開發環境下的桌面應用啟動腳本
import webview
import threading
import subprocess
import time
import sys
from flask import Flaskdef run_flask():"""在子進程中啟動Flask開發服務器"""# 確定Python可執行文件路徑python_exe = sys.executable# 啟動Flask應用server = subprocess.Popen([python_exe, 'app.py'],stdout=subprocess.PIPE,stderr=subprocess.STDOUT,universal_newlines=True)# 等待服務器啟動for line in server.stdout:print(line.strip())if 'Running on' in line:breakreturn serverclass Api:"""供前端JavaScript調用的Python API"""def multiply_numbers(self, a, b):"""示例函數:計算兩個數的乘積"""return a * bif __name__ == '__main__':# 啟動Flask服務器flask_server = run_flask()try:# 創建API實例api = Api()# 創建PyWebView窗口window = webview.create_window(title="PyWebView桌面應用",url="http://localhost:5000",width=800,height=600,resizable=True,fullscreen=False,js_api=api # 暴露Python API給JavaScript)# 啟動PyWebView主循環webview.start(debug=True)finally:# 關閉Flask服務器if flask_server:flask_server.terminate()flask_server.wait()print("Flask服務器已關閉")
3. 生產環境啟動腳本(desktop_prod.py)
# desktop_prod.py - 生產環境下的桌面應用啟動腳本
import webview
import threading
import subprocess
import time
import sys
from waitress import serve
from app import appclass Api:"""供前端JavaScript調用的Python API"""def multiply_numbers(self, a, b):"""示例函數:計算兩個數的乘積"""return a * bdef run_waitress():"""使用waitress啟動Flask應用(生產環境)"""print("正在啟動Waitress服務器...")serve(app, host='127.0.0.1', port=5000, threads=8)if __name__ == '__main__':# 在后臺線程中啟動waitress服務器server_thread = threading.Thread(target=run_waitress, daemon=True)server_thread.start()# 等待服務器啟動(給服務器一些時間初始化)print("等待服務器啟動...")time.sleep(2)try:# 創建API實例api = Api()# 創建PyWebView窗口window = webview.create_window(title="PyWebView桌面應用",url="http://localhost:5000",width=800,height=600,resizable=True,fullscreen=False,js_api=api # 暴露Python API給JavaScript)# 啟動PyWebView主循環(關閉調試模式)webview.start(debug=False)except Exception as e:print(f"應用啟動失敗: {e}")finally:print("應用已關閉")
4. 運行說明
開發環境
-
安裝依賴:
pip install flask pywebview waitress
-
運行開發環境腳本:
python desktop_dev.py
- 會自動啟動Flask開發服務器和PyWebView窗口。
- 修改代碼后刷新頁面即可看到變化。
生產環境
-
打包應用(可選):
pyinstaller --onefile --windowed desktop_prod.py
-
直接運行生產環境腳本:
python desktop_prod.py
- 使用waitress服務器替代Flask內置服務器,性能更好。
- 關閉了調試模式,更安全穩定。
功能說明
-
前后端交互:
- 前端通過
fetch
調用Flask API(如/api/data
)。 - 前端通過
window.pywebview.api
調用Python函數(如multiply_numbers
)。
- 前端通過
-
界面特點:
- 使用Tailwind CSS風格的界面(內聯樣式確保打包時不丟失)。
- 支持中文顯示(使用
Microsoft YaHei
字體)。 - 響應式設計,適配不同屏幕尺寸。
這個實現可以作為Windows桌面應用的基礎框架,你可以根據需要擴展Flask API或修改前端界面。
另一個應用示例代碼
# create Desktop App by pywebview
"""
Replace the flask module with waitress module.
To avoid the warning: WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
"""import webview
from flask import Flask, render_template_string
import threading
from waitress import serve# Create a Flask application
app = Flask(__name__)# Define the route
@app.route('/')
def index():return render_template_string("""<!DOCTYPE html><html lang="zh"><head><meta charset="UTF-8"><title>Pywebview + Flask 示例</title></head><body><h1>歡迎使用 Pywebview 和 Flask 構建的桌面應用!</h1><a href="http://cnliutz.ipyingshe.net">Blog Site</a> </body></html>""")def create_webview():# Define the URL of the Flask application to loadurl = "http://127.0.0.1:5000"# Create a window and load the specified URLwindow = webview.create_window('Pywebview + Flask 應用', url)# Run the applicationwebview.start()if __name__ == '__main__':# Start the Waitress server in a separate threaddef run_waitress():try:# Start Waitress to run the Flask applicationserve(app, host='127.0.0.1', port=5000)except Exception as e:print(f"Error starting Waitress: {e}")waitress_thread = threading.Thread(target=run_waitress)waitress_thread.daemon = Truewaitress_thread.start()# Start pywebviewcreate_webview()