Python传递字节数组字符串转JS ArrayBuffer及GLB加载异常问题
问题解决:PyQt5 QWebChannel传递GLB二进制数据到Web端
问题根源
你当前的错误是因为Python中str(file.read())的用法完全错误:它会把字节对象转换成字符串表示形式(比如b'\x47\x4C\x54\x46'),而不是把二进制数据转成可还原的字符串。JS端拿到这个带b''的字符串后,用TextEncoder.encode()得到的是这个字符串的UTF-8编码字节,完全不是原始的GLB二进制数据,导致GLTFLoader误将其当作JSON解析,从而抛出Unexpected token b in JSON at position 0错误。
正确解决方案
方案1:使用Base64编码传递(兼容所有场景)
通过Base64将二进制数据编码为字符串传递,再在JS端解码回ArrayBuffer,是跨语言传递二进制数据的通用方案。
Python端代码修改:
import base64 from PyQt5.QtCore import pyqtSlot @pyqtSlot(result=str) def load_binary_data(self): # 用with语句确保文件正确关闭 with open("model.glb", "rb") as file: byte_data = file.read() # 将二进制数据编码为Base64字符串并返回 return base64.b64encode(byte_data).decode("utf-8")
JavaScript端代码修改:
bridge.load_binary_data((base64Str) => { // 解码Base64字符串为ArrayBuffer const binaryString = atob(base64Str); const buffer = new ArrayBuffer(binaryString.length); const uint8Array = new Uint8Array(buffer); for (let i = 0; i < binaryString.length; i++) { uint8Array[i] = binaryString.charCodeAt(i); } // 加载GLB模型 const loader = new GLTFLoader(); loader.parse(buffer, '', (gltf) => { // 这里处理加载后的模型,比如添加到场景 scene.add(gltf.scene); }); });
方案2:直接传递QByteArray(更高效,推荐)
QWebChannel原生支持传递QByteArray类型,不需要额外编码,性能更优。
Python端代码修改:
from PyQt5.QtCore import pyqtSlot, QByteArray @pyqtSlot(result=QByteArray) def load_binary_data(self): with open("model.glb", "rb") as file: byte_data = file.read() # 直接返回QByteArray类型 return QByteArray(byte_data)
JavaScript端代码修改:
bridge.load_binary_data((byteArray) => { // QWebChannel会自动将QByteArray转换为JS的ArrayBuffer/Uint8Array const loader = new GLTFLoader(); loader.parse(byteArray, '', (gltf) => { scene.add(gltf.scene); }); });
内容的提问来源于stack exchange,提问作者Miger
相关产品推荐
相关产品推荐

