Python调用Inkscape Shell模式,如何获取query-all命令的输出?
解决Inkscape Shell模式下捕获
query-all输出的问题 核心问题分析
你当前无法捕获query-all输出的主要原因是启用了shell=True,额外启动的Shell层会干扰Inkscape原生输出的捕获。同时,Inkscape Shell模式会以>作为命令提示符,需要通过识别提示符来分离命令输出与系统提示。
解决方案与修改后的代码
import subprocess import tempfile import os import threading # 后台线程处理stderr,防止缓冲区满导致进程阻塞 def handle_stderr(process): for line in iter(process.stderr.readline, ''): # 可根据需求改为日志记录或其他处理 print(f"Inkscape错误输出: {line.strip()}") INKSCAPE_EXE_PATH = "你的Inkscape可执行文件路径" LIST_OF_SVGs = [] # 替换为你的SVG内容列表 # 启动Inkscape Shell模式,移除shell=True避免额外Shell层 process = subprocess.Popen( [INKSCAPE_EXE_PATH, "--shell"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, bufsize=1 # 行缓冲,便于逐行读取输出 ) # 启动stderr处理线程 stderr_thread = threading.Thread(target=handle_stderr, args=(process,)) stderr_thread.daemon = True stderr_thread.start() # 读取Inkscape启动后的初始提示符> process.stdout.readline() def create_image_data(SVGs): page = 0 # 自定义页码计数,按需调整 for svg in SVGs: filename = f"svg_output" # 自定义基础文件名 # 创建临时SVG文件,退出with块自动删除 with tempfile.NamedTemporaryFile(delete=True, suffix='.svg', mode='wb') as temp_svg: temp_svg.write(svg.encode('utf-8')) temp_svg.flush() temp_svg_path = temp_svg.name # 打开SVG文件并确认执行完成 process.stdin.write(f"file-open:{temp_svg_path}\n") process.stdin.flush() process.stdout.readline() # 读取执行后的提示符> # 设置导出路径并确认 export_path = os.path.join(os.getcwd(), f'{filename}-{page}.png') process.stdin.write(f"export-filename:{export_path}\n") process.stdin.flush() process.stdout.readline() # 执行导出并确认 process.stdin.write("export-do\n") process.stdin.flush() process.stdout.readline() # 执行query-all并捕获输出 process.stdin.write("query-all\n") process.stdin.flush() # 读取输出直到遇到提示符>,提取有效数据 bbox_lines = [] while True: line = process.stdout.readline() if not line: break stripped_line = line.strip() if stripped_line == ">": break if stripped_line: bbox_lines.append(stripped_line) # 解析边界框数据(格式:id x y width height) bbox_data = [] for line in bbox_lines: parts = line.split() if len(parts) >=5: bbox_data.append({ "元素ID": parts[0], "X坐标": float(parts[1]), "Y坐标": float(parts[2]), "宽度": float(parts[3]), "高度": float(parts[4]) }) print(f"第{page}个SVG的边界框数据: {bbox_data}") page +=1 # 退出Inkscape process.stdin.write("quit\n") process.stdin.flush() # 执行转换与数据提取 create_image_data(LIST_OF_SVGs) # 等待进程结束 process.wait()
关键修改说明
- 移除
shell=True:直接启动Inkscape进程,避免中间Shell层干扰输出捕获。 - 行缓冲配置:
bufsize=1让stdout按行缓冲,保证输出能实时读取。 - stderr后台处理:单独线程读取错误输出,防止缓冲区满导致进程挂起。
- 提示符识别:每次命令执行后读取到
>提示符确认完成;query-all输出通过读取到下一个>来提取有效内容。 - 临时文件自动清理:设置
delete=True,避免临时文件残留。
内容的提问来源于stack exchange,提问作者Dani
相关产品推荐
相关产品推荐

