import webview import threading import time,os CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) # ---------------------- 1. 定义供 JS 调用的 Python 函数 ---------------------- class Api: """暴露给 JS 的 Python 接口类(所有方法都会被 JS 访问)""" def __init__(self): self.window = None # 保存窗口实例,用于 Python 主动调用 JS def set_window(self, window): """初始化时绑定窗口实例""" self.window = window def python_hello(self, name): """JS 调用的同步函数:接收参数,返回结果""" print(f"[Python] 收到 JS 调用,参数:{name}") return f"Hello {name}! 这是 Python 返回的消息" def python_async_task(self, duration): """JS 调用的异步函数:模拟耗时任务(不阻塞前端)""" def async_task(): print(f"[Python] 开始异步任务,耗时 {duration} 秒") time.sleep(int(duration)) # 异步任务完成后,主动调用 JS 函数通知结果 self.window.evaluate_js(f'js_receive_python_msg("异步任务完成!耗时 {duration} 秒")') print(f"[Python] 异步任务结束") # 启动子线程执行异步任务,避免阻塞 UI threading.Thread(target=async_task, daemon=True).start() return "异步任务已启动,请等待结果通知" def python_close_window(self): """JS 调用关闭窗口""" print("[Python] 收到关闭窗口请求") self.window.destroy() # ---------------------- 2. Python 主动调用 JS 函数 ---------------------- def python_call_js_periodically(window): """Python 定时调用 JS 函数(模拟主动推送数据)""" count = 0 while window.is_alive(): count += 1 # 执行 JS 函数,传递参数 window.evaluate_js(f'js_receive_python_msg("Python 主动推送:第 {count} 条消息")') time.sleep(3) # 每 3 秒推送一次 if count >= 5: break # ---------------------- 3. 启动窗口 ---------------------- if __name__ == "__main__": # 创建 API 实例 api = Api() # 加载本地 HTML 文件(也可加载远程 URL:url="https://xxx.com") window = webview.create_window( title="PyWebView 双向通信示例", url=f"file:///{CURRENT_DIR}/templates/app_JsToPy.html", resizable=True, js_api=api # 关键:暴露 Python API 给 JS ) # 绑定窗口实例到 API(供异步任务调用 JS) api.set_window(window) # 启动 Python 主动调用 JS 的线程(非阻塞) t = threading.Thread(target=python_call_js_periodically, args=(window,), daemon=True) t.start() # 运行窗口(阻塞主线程) webview.start( debug=True, # 开发环境开启调试,生产环境关闭 http_server=True # 启用内置 HTTP 服务器(加载本地 HTML 必需) )