使用pywebview+Paper.js绘制Path不显示,如何解决?
解决PyWebView中Paper.js Path无法渲染的问题
出现这个问题的核心原因有两个:
- 设置HTML后立即执行JS代码时,Paper.js脚本可能还未加载完成,导致Paper.js的API无法正常调用
- 绘制完成后立即获取Canvas数据,此时Paper.js的渲染操作可能还未完成,Canvas仍为空白
以下是修复后的代码:
import io from PIL import Image import base64 import webview def extract_image(width, height, path=[(100, 100)]): color = 'red' def callback(window): # 编写完整的HTML页面,将JS代码放在DOM加载完成的回调中 window.html = f""" <script type="text/javascript" src="js/paper.js"></script> <canvas id="myCanvas" width="{width}" height="{height}"></canvas> <script> window.onload = function() {{ var canvas = document.getElementById("myCanvas"); paper.setup(canvas); var start = new paper.Point({path[0][0]}, {path[0][1]}); var end = new paper.Point({path[0][0] + 1}, {path[0][1]}); var path = new paper.Path({{ segments: [start, end], strokeColor: '{color}', strokeCap: 'round', strokeJoin: 'round', strokeWidth: 10 }}); path.add(new paper.Point(200, 200)); paper.view.draw(); // 标记绘制完成 window.drawComplete = true; }} </script> """ # 等待绘制完成 def wait_for_draw(): if window.evaluate_js("window.drawComplete === true"): # 获取Canvas数据 data_url = window.evaluate_js("canvas.toDataURL()") base64_data = data_url.split(",")[1] image_data = io.BytesIO(base64.b64decode(base64_data)) image = Image.open(image_data) image.show() window.destroy() else: # 延迟100ms再次检查 webview.timer(100, wait_for_draw) # 启动等待检查 wait_for_draw() return callback def extract_canvas_to_image(): return webview.create_window('Hello world', frameless=True, hidden=True) if __name__ == '__main__': window = extract_canvas_to_image() webview.start(extract_image(400, 400), window)
关键修改说明:
- 将绘制逻辑放在
window.onload事件中,确保Paper.js脚本和Canvas元素都已加载完成后再执行绘制 - 通过
window.drawComplete标记绘制状态,使用定时器等待绘制完成后再获取Canvas数据,避免渲染未完成就截图 - 移除了原代码中直接同步执行JS的逻辑,改为在HTML中内嵌脚本,保证执行时机正确
额外注意事项:
- 确认
js/paper.js文件路径正确,保证PyWebView能加载到该脚本 - 若使用新版本PyWebView,也可通过
window.loaded事件触发后续操作,进一步保证窗口初始化完成
内容的提问来源于stack exchange,提问作者Avi
相关产品推荐
相关产品推荐

