You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从另一个multiprocessing.Process中访问pywebview.Window对象?

问题核心原因

multiprocessing创建的子进程和主进程内存空间完全隔离,主进程中创建的pywebview.Window实例无法直接在子进程中访问调用,你需要通过进程间通信(IPC) 传递要执行的JS指令,由主进程操作Window实例执行。

可行实现方案

我们可以用multiprocessing.Queue作为跨进程通信通道,Flask子进程把需要执行的JS代码写入队列,主进程定时轮询队列,读取到JS代码后调用evaluate_js执行即可。

修改后的完整代码

from flask import Flask, request, jsonify
import os, sys, re, json, socket, sqlite3, base64, requests, webview
import multiprocessing
from flask_cors import CORS

# 你原来未定义的常量补默认值,可替换为自己的配置
Root_Dir = os.path.dirname(os.path.abspath(__file__))
Server_Host = "127.0.0.1"
Server_Port = 5000

class ServerFlaskApi:
    def __init__(self, msg_queue):
        # 接收主进程传过来的队列,用来传递JS指令
        self.msg_queue = msg_queue
        self.app = Flask(__name__, root_path=Root_Dir)
        self.app.add_url_rule("/", view_func=self.Default)
        self.app.add_url_rule("/print_console", view_func=self.PrintToWebViewConsole)

    def Default(self):
        return "Welcome to the Python Http Server for your Application!", 200
    def PrintToWebViewConsole(self):
        # 把要执行的JS代码放到队列里,不要直接调用Window对象
        js_script = "console.log('这是Flask进程传来的日志')"
        self.msg_queue.put(js_script)
        return jsonify({"status": "ok"})

################
class WebviewApi:
    def __init__(self, msg_queue):
        self.server_process = None
        # 保存队列,启动Flask的时候传给子进程
        self.msg_queue = msg_queue
    def StartServer(self):
        # 把队列作为参数传给Flask启动函数
        self.server_process = multiprocessing.Process(target=Run_Flask_Server, args=(self.msg_queue,), daemon=True)
        self.server_process.start()
        return "服务启动成功"
    def StopServer(self):
        if self.server_process and self.server_process.is_alive():
            self.server_process.terminate()
            self.server_process.join()
        return "服务已停止"

def Run_Flask_Server(msg_queue):
    # 子进程接收队列,传给Flask实例
    serverApi = ServerFlaskApi(msg_queue)
    CORS(serverApi.app)
    serverApi.app.run(host=Server_Host, port=Server_Port, debug=True, use_reloader=False)
################
if __name__ == "__main__":
    # 1. 先创建跨进程队列
    msg_queue = multiprocessing.Queue()
    # 2. 把队列传给WebviewApi
    WebViewApi = WebviewApi(msg_queue)
    WebviewWindow = webview.create_window(
        title="Server Monitor", 
        url="view/main-gui.html", 
        js_api=WebViewApi, 
        width=550, height=750, 
        min_size=(550, 750), 
        resizable=False, 
        on_top=True, 
        confirm_close=False
    )

    # 3. 定义轮询队列的函数,每隔50ms检查一次队列里有没有要执行的JS
    def check_queue():
        while not msg_queue.empty():
            try:
                js_code = msg_queue.get_nowait()
                WebviewWindow.evaluate_js(js_code)
            except:
                pass
        # 重复执行当前函数
        webview.create_timer(0.05, check_queue)

    # 启动队列检查定时器
    webview.create_timer(0.05, check_queue)
    webview.start(debug=False)

注意事项

  • 所有和pywebview.Window相关的操作都必须在主进程执行,子进程只负责传递JS指令
  • 队列只能传递可序列化的对象,字符串格式的JS代码完全满足要求
  • 定时器的间隔可以根据需求调整,0.05秒(50毫秒)的间隔平衡了性能和响应速度
  • 停止Flask服务时要先调用terminate()再调用join(),避免出现僵尸进程

内容的提问来源于stack exchange,提问作者KiddoV

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 02:18:04