开发者

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

目录
  • pywebview的用途与特点
  • 基本使用方法
    • 1. 安装
    • 2. 简单示例(python与html交互)
  • 结合Flask与waitress开发应用
    • 架构设计
    • 开发环境代码示例
  • 生产环境配置(使用waitress)
    • 1. 修改Flask应用(app.py)
    • 2. 使用waitress启动Flask
    • 3. 修改PyWebView应用(desktop.py)
  • 打包应用的建议
    • 总结
      • 完整代码
        • 1. Flask后端代码(app.py)
        • 2. 开发环境启动脚本(desktop_dev.py)
        • 3. 生产环境启动脚本(desktop_prod.py)
        • 4. 运行说明
          • 开发环境
          • 生产环境
        • 功能说明
        • 另一个应用示例代码

          pywebview的用途与特点

          用途

          pywebview是一个轻量级Python库,用于创建桌面应用程序(GUI)。它通过嵌入Web浏览器组件(如Windows的Edge/IE、MACOS的WebKit、linux的GTK WebKit),允许开发者使用HTML/css/JavaScript构建界面,python并用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开发应用

          架构设计

          • Flask:提供Web API,处理业务逻辑。
          • pywebview:作为桌面应用的外壳,加载Flask的Web界面。
          • waitress:在生产环境中替代Flask内置服务器,提供更好的性能。

          开发环境代码示例

          # 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 sub编程客栈process
          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

          注意事项

          • 打包时需确保包含所有依赖项(如Flask、waitress、pywebview)。
          • 在macOS/Linux上可能需要额外配置以确保WebView组件正确加载。

          总结

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

          • 开发阶段:使用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 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内置服务器,性能更好。
            • 关闭了调试模式,更安全稳定。

          功能说明

          • 前后端交互

            • 前端通过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.android 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(fphp"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桌面应用程序内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

          0

          上一篇:

          下一篇:

          精彩评论

          暂无评论...
          验证码 换一张
          取 消

          最新开发

          开发排行榜