Python 使用 pywebview 开发桌面应用


本文由 简悦 SimpRead 转码, 原文地址 juejin.cn

前言

之前用过 Eel 做的桌面应用觉得已经够屌了, 不过由于 Eel 是调用 Chrome, 时常出现各种小问题, 比如窗口大小设置后有时候不管用, 鼠标右键菜单无法禁用 (一眼就能看出来是个 web). 而且尝试了用 pyinstaller 打包后文件好大, 昨天晚上闲逛又发现了个比 Eel 更好的解决方案pywebview, 更轻量, 可自定义的设置更多. 由于pywebview是直接调用系统自身的浏览器 (Win10 调用 Edge,Win7 调用 IE), 因此很适合打包发布. 官网:pywebview.flowrl.com/

最简单应用上手

先装上轮子

pip install pywebview

实现一个内嵌百度首页的winform程序, 固定窗口大小, 禁止选择文字

"""
main.py
"""
import webview

window = webview.create_window(
    title='百度一下,全是广告',
    url='http://www.baidu.com',
    width=850,
    height=600,
    resizable=False,    # 固定窗口大小
    text_select=False,   # 禁止选择文字内容
    confirm_close=True   # 关闭时提示
)
webview.start()

无论是启动速度, 还是显示效果都要比 Eel 好很多. 退出提示的窗口默认显示的是英文, 可以本地化一下, 定义个字典传给webview.start()当启动参数就行了.

chinese = {
    'global.quitConfirmation': u'确定关闭?',
}
webview.start(localization=chinese)

高阶应用

在 HTML 前端界面中调用 Python 中的函数

Http 是由 Flask 提供的, 直接将 Flask 实例化对象 app 传给url参数就行了

import webview
from flask import Flask, render_template

# 实例化flask对象
app = Flask(__name__)

# 定义路由渲染模板
@app.route('/')
def index():
    return render_template('/index.html')

# 配置pywebview关闭提示的中文翻译
chinese = {
    'global.quitConfirmation': u'确定关闭?',
}

# 传给前端的api对象, 定义了一个可以通过js调用退出当前应用的函数
class Api:
    def __init__(self) -> None:
        self._window = None

    def set_window(self, window):
        self._window = window

    def quit(self):
        self._window.destroy()

if __name__ == '__main__':
    # 实例化Api类
    api = Api()
    window = webview.create_window(
        title='我是一个标题',
        url=app,
        fullscreen=True,    # 以全屏模式启动
        # width=760,    # 自定义窗口大小
        # height=390,
        # resizable=False,  # 固定窗口大小
        text_select=False,  # 禁止选择文字内容
        confirm_close=True,  # 关闭时提示
        js_api=api  # 将上面实例化后的Api对象传给前端js调用
    )
    # --划重点--务必记得需要将上面创建的window对象再通过函数传给实例化后的api对象
    api.set_window(window)
    # 启动程序
    webview.start(localization=chinese)

前端写一个 id 为exit的 button, jquery 给它绑定个点击的事件来调用 api 函数方法, 注意这里的pywebview.api是在 pywebview 的应用启动后自动注入到当前浏览器窗口中的全局对象, python 中写的函数就绑定在它下面.

$("#exit").click(function () {
    pywebview.api.quit();
})

打包成单个 EXE 文件

之前用pyinstaller手工打包太麻烦了, 发现个图形化的配置 pyinstaller 进行打包的工具: auto-py-to-exe, 用 pip 装一下, 然后就可以直接启动了

pip install auto-py-to-exe
# 启动工具
auto-py-to-exe

这工具居然是用eel写的, 哈哈...

推荐使用单目录方式进行打包, 单文件的话可能会对程序代码中涉及到路径引用的地方出现问题, 坑有点大, 不推荐使用.

需要注意的是要在附加文件一块设置中将 flask 涉及到的模板, 静态文件, 还有其他诸如 sqlite 数据库文件都添加进去

判断页面中 pywebview.api 对象是否加载成功

今天又写了个小应用, 调用的本地的 html 文件, 想要在页面打开的时候直接调用pywebview.api中关联的 python 函数, 但是由于页面中直接用 js 访问pywebview.api对象的话会报错找不到对象, 又翻了下官方文档, 发现需要给window对象添加个事件监听pywebviewready, 示例代码:

<script>
  window.addEventListener('pywebviewready', function () {
    pywebview.api.hl('aaa').then(function (res) {
      document.querySelector('#hl').textContent = res.rate
    })
  })
</script>

声明:HEUE NOTE|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA 4.0协议进行授权

转载:转载请注明原文链接 - Python 使用 pywebview 开发桌面应用