如何将任意深度嵌套Python OrderedDict转换为QJSValue
问题原因
你的代码存在两个核心错误导致输出异常:
- 递归逻辑错误:处理嵌套OrderedDict时,直接将根级prototype传入递归调用,所有层级的属性都被写入根对象,最终结构扁平化
- 列表创建错误:直接实例化
QJSValue()得到的不是合法JS数组对象,必须通过QJSEngine.newArray()创建数组,否则索引赋值无效,最终列表字段显示为None
方案1:基于已有原型填充值
适用于你已经提前定义好原型结构,只需要填充值的场景:
from collections import OrderedDict from PySide6.QtCore import QJSEngine, QJSValue def fill_qjs_prototype(od: OrderedDict, prototype: QJSValue) -> QJSValue: for field_name, inner_dict_or_value in od.items(): # 从原型中取出对应字段的已有子对象/数组作为递归目标 target_js_val = prototype.property(field_name) if isinstance(inner_dict_or_value, OrderedDict): # 递归填充嵌套OrderedDict fill_qjs_prototype(inner_dict_or_value, target_js_val) prototype.setProperty(field_name, target_js_val) elif isinstance(inner_dict_or_value, list): # 填充原型中已创建的数组 for idx, item in enumerate(inner_dict_or_value): target_js_val.setProperty(idx, item) prototype.setProperty(field_name, target_js_val) else: # 基本类型直接赋值 prototype.setProperty(field_name, inner_dict_or_value) return prototype
使用方法:直接传入你的OrderedDict和提前创建好的prototype即可:
fill_qjs_prototype(od, prototype) print(prototype.toVariant())
方案2:无需提前定义原型,通用转换方案
不需要提前写原型结构,支持任意深度的嵌套OrderedDict自动转换为QJSValue,更灵活:
from collections import OrderedDict from PySide6.QtCore import QJSEngine, QJSValue def ordered_dict_to_qjs(od: OrderedDict, engine: QJSEngine) -> QJSValue: js_obj = engine.newObject() for key, value in od.items(): if isinstance(value, OrderedDict): # 递归生成嵌套JS对象 sub_js_obj = ordered_dict_to_qjs(value, engine) js_obj.setProperty(key, sub_js_obj) elif isinstance(value, list): # 自动创建JS数组并填充 js_arr = engine.newArray(len(value)) for idx, item in enumerate(value): js_arr.setProperty(idx, item) js_obj.setProperty(key, js_arr) else: # 基本类型直接赋值 js_obj.setProperty(key, value) return js_obj
使用方法:
if __name__ == "__main__": from PySide6.QtCore import QCoreApplication app = QCoreApplication() engine = QJSEngine() # 你的OrderedDict对象od result_js = ordered_dict_to_qjs(od, engine) print(result_js.toVariant())
注意:如果使用原型填充方案,需要确保提前定义的原型字段、类型和嵌套结构与输入的OrderedDict完全匹配,否则会出现属性丢失的问题。如果结构不固定,推荐使用无需原型的通用转换方案。
内容的提问来源于stack exchange,提问作者Blue7
相关产品推荐
相关产品推荐

