Pywebview:Web技术构建桌面应用的最佳选择

大家好,我是唐叔。今天我们来聊聊一个非常轻量且强大的Python库------pywebview。如果你曾经为开发一个简单的桌面应用而纠结于Electron的笨重、PyQt的复杂,或是Tkinter的界面简陋,那pywebview或许正是你一直在找的解决方案。

一、介绍

pywebview 是一个轻量级的跨平台Python库,它允许你在一个原生窗口中嵌入Web技术(HTML/CSS/JS)来构建GUI界面。本质上,它就是一个迷你浏览器内核,让你可以用写网页的方式写桌面应用。

与其他桌面框架对比:

  • Electron:功能强大,但打包体积大、内存占用高。

  • PyQt/Tkinter:原生控件,但界面现代化程度低、开发效率不高。

  • pywebview轻量、跨平台、易上手,适合快速开发中小型桌面应用,尤其是已有Web前端的项目。

二、安装

安装全量版本

bash 复制代码
pip install pywebview

安装指定环境版本

如果你希望控制依赖版本,可以使用:

bash 复制代码
pip install pywebview[qt]  # 使用Qt后端
pip install pywebview[cef] # 使用CEF后端

三、使用入门

3.1 基本使用

来看一个最简单的例子:

python 复制代码
import webview

def main():
    window = webview.create_window('Hello pywebview', 'https://pywebview.flowrl.com')
    webview.start()

if __name__ == '__main__':
    main()

函数说明

  • create_window():创建窗口,参数包括标题和初始URL或本地HTML路径。
  • start():启动GUI事件循环。

3.2 应用程序架构

纯网络服务架构

就如上文的基本使用,前端只需暴露应用服务器,后端调用即可

python 复制代码
import webview

if __name__ == '__main__':
    webview.create_window("My App", "http://localhost:3000")
    webview.start(http_server=True, port=3000)

官网有完整的示例 基于 Flask 的应用程序 供参考学习。

无服务器架构

完全不使用网络服务器,通过 webview.create_window(...html='') 或者 window.load_html 加载 HTML。

前端HTMLindex.html):

html 复制代码
<!DOCTYPE html>
<html>
<body>
    <h1>Hello from HTML!</h1>
</body>
</html>

后端Python

python 复制代码
import webview

webview.create_window("Local App", "index.html")
webview.start()

根据官网说明:这种方法有一些限制,因为在加载的页面上下文中没有文件系统。图片和其他资源只能通过 Base64 内联加载。

3.3 JS与Python交互

pywebview 支持在JS中调用Python函数,也支持在Python中调用JS方法。

下述是JS中调用Python函数的代码示例:

Python端

python 复制代码
import webview

class Api:
    def get_message(self):
        return "Hello from Python!"

if __name__ == '__main__':
    api = Api()
    window = webview.create_window('JS 接口 示例', 'index.html', js_api=api)
    webview.start()

JS端(在HTML中):

html 复制代码
<!DOCTYPE html>
<html>
<body>
    <button onClick="greet()">打招呼</button>
</body>
<script>
function greet() {
    pywebview.api.get_message().then(function(message) {
        alert(message);
    });
}
</script>
</html>

✅ 推荐将Python逻辑封装成API,JS中异步调用,保持前后端分离。

四、应用打包

使用 pyinstaller 打包你的应用:

bash 复制代码
pyinstaller --onefile --windowed your_script.py

打包后会生成一个独立的可执行文件,可在没有Python环境的机器上运行。

有关 pyinstaller 的介绍,详情请查阅唐叔的这篇文章:告别Python环境依赖!用PyInstaller打包EXE的终极指南_python打包成exe-CSDN博客

五、常见使用场景

5.1 文件操作

文件下载

你可以使用Python控制文件下载路径,或由前端触发下载。

python 复制代码
import webview

if __name__ == '__main__':
    # 创建一个标准的 webview 窗口
    webview.settings['ALLOW_DOWNLOADS'] = True
    window = webview.create_window('Simple browser', 'https://pywebview.idepy.com/download')
    webview.start()

文件拖放

下述是常见的文件拖放效果,实际上是通过拖放后获取到文件路径,进而通过文件路径调用相关API再进一步操作文件。

python 复制代码
import webview
from webview.dom import DOMEventHandler

def on_drag(e):
    pass

def on_drop(e):
    files = e['dataTransfer']['files']
    if len(files) == 0:
        return

    print(f'事件类型: {e["type"]}。被拖入的文件:')

    for file in files:
        print(file.get('pywebviewFullPath'))

def bind(window):
    window.dom.document.events.dragenter += DOMEventHandler(on_drag, True, True)
    window.dom.document.events.dragstart += DOMEventHandler(on_drag, True, True)
    window.dom.document.events.dragover += DOMEventHandler(on_drag, True, True, debounce=500)
    window.dom.document.events.drop += DOMEventHandler(on_drop, True, True)

if __name__ == '__main__':
    window = webview.create_window(
        '拖放示例', html='''
            <html>
                <body style="height: 100vh;"->
                    <h1>将文件拖放到此处</h1>
                </body>
            </html>
        '''
    )
    webview.start(bind, window)

5.2 自定义菜单

pywebview 支持自定义系统菜单:

python 复制代码
import webview
import webview.menu as wm

def change_active_window_content():
    active_window = webview.active_window()
    if active_window:
        active_window.load_html('<h1>You changed this window!</h1>')

def click_me():
    active_window = webview.active_window()
    if active_window:
        active_window.load_html('<h1>You clicked me!</h1>')

def do_nothing():
    pass

def say_this_is_window_2():
    active_window = webview.active_window()
    if active_window:
        active_window.load_html('<h1>This is window 2</h2>')

def open_file_dialog():
    active_window = webview.active_window()
    active_window.create_file_dialog(webview.SAVE_DIALOG, directory='/', save_filename='test.file')

if __name__ == '__main__':
    window_1 = webview.create_window(
        'Application Menu Example', 'https://pywebview.idepy.com/hello'
    )
    window_2 = webview.create_window(
        'Another Window', html='<h1>Another window to test application menu</h1>'
    )

    menu_items = [
        wm.Menu(
            'Test Menu',
            [
                wm.MenuAction('Change Active Window Content', change_active_window_content),
                wm.MenuSeparator(),
                wm.Menu(
                    'Random',
                    [
                        wm.MenuAction('Click Me', click_me),
                        wm.MenuAction('File Dialog', open_file_dialog),
                    ],
                ),
            ],
        ),
        wm.Menu('Nothing Here', [wm.MenuAction('This will do nothing', do_nothing)]),
    ]

    webview.start(menu=menu_items)

💡 你也可以完全用HTML+CSS在前端构建菜单,更灵活美观。

5.3 图标设置

使用 webview.start(icon=<file_path>) 设置窗口图标。

python 复制代码
import webview

if __name__ == '__main__':
    window = webview.create_window('Set window icon', 'https://pywebview.idepy.com/hello')
    webview.start(icon='../logo/logo.png')

此方法仅在 GTK 和 QT 平台上受支持。其他平台的图标将在冻结过程中设置。

六、总结

pywebview 是一个非常灵活且强大的工具,尤其适合:

  • 已有Web前端,想快速封装成桌面应用;
  • 希望用HTML/CSS/JS构建现代化界面;
  • 对应用体积和内存占用有要求的场景;
  • 需要跨平台运行(Windows/macOS/Linux)。

它的学习曲线平缓,社区活跃,文档完善,是Python开发者进军桌面应用开发的绝佳选择。

如果你正在寻找一个轻量、高效、易扩展 的桌面开发方案,不妨试试 pywebview,相信它会给你带来惊喜。

唐叔说

技术选型没有绝对的好坏,只有适合与否。pywebview 在我多个中小项目中表现出色,尤其是在快速原型和内部工具开发中。希望这篇指南能帮你少走弯路,早日打造出属于自己的桌面应用!

如果有新的想法,欢迎在评论区留言,我们一起交流进步!🎉


参考资料

相关推荐
qq_402605652 小时前
python爬虫(三) ---- 分页抓取数据
开发语言·爬虫·python
我是Feri2 小时前
机器学习之线性回归下的数据预处理:数据清洗的艺术(食材筛选指南)
开发语言·python·机器学习
卷Java3 小时前
预约记录关联查询接口说明
java·开发语言·spring boot·python·微信小程序
算法与编程之美3 小时前
探索flatten的其他参数用法及对报错异常进行修正
人工智能·pytorch·python·深度学习·机器学习
IT_陈寒3 小时前
5种JavaScript性能优化技巧:从V8引擎原理到实战提速200%
前端·人工智能·后端
蒋星熠3 小时前
Maven项目管理与构建自动化完全指南
java·前端·python·自动化·maven
Ykkk_3 小时前
小土堆pytorch
人工智能·pytorch·python
FriendshipT3 小时前
图像分割:PyTorch从零开始实现SegFormer语义分割
人工智能·pytorch·python·深度学习·目标检测·语义分割·实例分割
shelter -唯3 小时前
基于selenium库的爬虫实战:京东手机数据爬取
爬虫·python·selenium