python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > python pywebview桌面应用程序

python的pywebview库结合Flask和waitress开发桌面应用程序完整代码

作者:czliutz

pywebview是轻量级Python库,用于创建跨平台桌面应用,结合HTML/CSS/JS界面与Python交互,支持Windows/macOS/Linux,资源占用低,可与Flask、Waitress集成,便于开发、部署,本文给大家介绍python的pywebview库结合Flask和waitress开发桌面应用程序简介,感兴趣的朋友一起看看吧

pywebview的用途与特点

用途
pywebview是一个轻量级Python库,用于创建桌面应用程序(GUI)。它通过嵌入Web浏览器组件(如Windows的Edge/IE、macOS的WebKit、Linux的GTK WebKit),允许开发者使用HTML/CSS/JavaScript构建界面,并用Python处理后端逻辑。这种方式结合了Web技术的灵活性和Python的强大功能,适合快速开发跨平台桌面应用。

特点

  1. 跨平台支持:原生支持Windows、macOS、Linux,无需额外配置。
  2. 轻量级:无需完整的浏览器,仅依赖系统内置Web组件。
  3. 双向通信:HTML前端与Python后端可互相调用函数。
  4. 简单易用:API简洁,学习成本低。
  5. 资源占用少:相比Electron等框架,内存占用更小。

基本使用方法

1. 安装

pip install pywebview

2. 简单示例(Python与HTML交互)

import webview
def 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开发应用

架构设计

开发环境代码示例

# app.py - Flask后端
from flask import Flask, jsonify
app = 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 subprocess
def run_flask():
    # 启动Flask应用(开发环境)
    subprocess.run(['python', 'app.py'])
if __name__ == '__main__':
    # 在后台线程中启动Flask
    flask_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, jsonify
app = 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 app
if __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 subprocess
def run_flask():
    # 启动Flask应用(生产环境使用waitress)
    subprocess.run(['python', 'server.py'])
if __name__ == '__main__':
    # 在后台线程中启动Flask
    flask_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)  # 生产环境关闭调试模式

打包应用的建议

为了将应用分发给最终用户,可以使用PyInstallercx_Freeze将Python代码打包成单个可执行文件:

# 使用PyInstaller打包
pyinstaller --onefile --windowed desktop.py

注意事项

总结

通过结合pywebviewFlaskwaitress,可以开发出兼具美观界面和强大功能的跨平台桌面应用:

完整代码

以下是在Windows平台上结合PyWebView、Flask和Waitress的完整代码实现。代码分为三个主要文件,分别负责Flask后端、桌面应用包装和生产环境启动。

1. Flask后端代码(app.py)

# app.py - Flask后端应用
from flask import Flask, jsonify, render_template_string
import os
app = 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 Flask
def 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:
            break
    return server
class Api:
    """供前端JavaScript调用的Python API"""
    def multiply_numbers(self, a, b):
        """示例函数:计算两个数的乘积"""
        return a * b
if __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 app
class Api:
    """供前端JavaScript调用的Python API"""
    def multiply_numbers(self, a, b):
        """示例函数:计算两个数的乘积"""
        return a * b
def 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. 运行说明

开发环境

  1. 安装依赖:

    pip install flask pywebview waitress
  2. 运行开发环境脚本:

    python desktop_dev.py
    • 会自动启动Flask开发服务器和PyWebView窗口。
    • 修改代码后刷新页面即可看到变化。

生产环境

  1. 打包应用(可选):

    pyinstaller --onefile --windowed desktop_prod.py
  2. 直接运行生产环境脚本:

    python desktop_prod.py
    • 使用waitress服务器替代Flask内置服务器,性能更好。
    • 关闭了调试模式,更安全稳定。

功能说明

这个实现可以作为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" rel="external nofollow" >Blog Site</a>                        
    </body>
    </html>
    """)
def create_webview():
    # Define the URL of the Flask application to load
    url = "http://127.0.0.1:5000"
    # Create a window and load the specified URL
    window = webview.create_window('Pywebview + Flask 应用', url)
    # Run the application
    webview.start()
if __name__ == '__main__':
    # Start the Waitress server in a separate thread
    def run_waitress():
        try:
            # Start Waitress to run the Flask application
            serve(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 = True
    waitress_thread.start()
    # Start pywebview
    create_webview()

到此这篇关于python的pywebview库结合Flask和waitress开发桌面应用程序完整代码的文章就介绍到这了,更多相关python pywebview桌面应用程序内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文