如何从另一个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
相关产品推荐
相关产品推荐

