如何在Python版DM脚本中遍历未知结构的TagGroup?
我之前也碰到过这个痛点——Python版的Py_TagGroup确实没有直接提供类似原生DM Script里TagGroupGetTagLabel()、TagGroupGetTagType()的遍历API,但我们可以绕个弯:利用Python和原生DM Script的交互机制,调用原生函数来实现所有需要的标签操作。
核心思路
Py_TagGroup本质是对原生DM Script TagGroup的封装,我们可以通过DM.Application().RunScriptString()执行一段原生DM Script代码,把Py_TagGroup传递进去,让原生代码帮我们完成遍历、读写等操作,再把结果返回给Python解析。
1. 遍历未知结构的TagGroup(含嵌套)
下面是一个可直接用的Python函数,能递归遍历TagGroup的所有标签,返回包含完整路径、类型、值的结构化信息:
def traverse_tag_group(tg): # 定义递归遍历的原生DM Script代码 dm_script = """ void TraverseTagGroupRecursive(TagGroup tg, string parent_path, TagGroup result, number &index) { number num_tags = tg.TagGroupCountTags(); for (number i=0; i<num_tags; i++) { string label; number type; tg.TagGroupGetTagLabel(i, label); tg.TagGroupGetTagType(i, type); string full_path = parent_path + "/" + label; variable val; if (type == 2) tg.TagGroupGetTagAsNumber(i, val); // 数字类型 else if (type == 3) tg.TagGroupGetTagAsString(i, val); // 字符串类型 else if (type == 7) { // 嵌套TagGroup TagGroup nested_tg; tg.TagGroupGetTagAsTagGroup(i, nested_tg); val = "[Nested TagGroup]"; // 递归遍历嵌套结构 TraverseTagGroupRecursive(nested_tg, full_path, result, index); } else val = "[Unsupported Type]"; // 可根据需求扩展其他类型 // 将标签信息存入结果TagGroup result.TagGroupSetTagAsString(index + "_path", full_path); result.TagGroupSetTagAsNumber(index + "_type", type); result.TagGroupSetTagAsString(index + "_value", val); index++; } } // 主逻辑:接收Python传入的TagGroup,执行遍历后返回结果 TagGroup input_tg = GetTagGroupFromScriptObject(0); TagGroup result_tg = NewTagGroup(); number tag_index = 0; TraverseTagGroupRecursive(input_tg, "", result_tg, tag_index); result_tg.TagGroupSetTagAsNumber("total_count", tag_index); SetScriptObject(result_tg); """ # 执行DM脚本并传递参数 app = DM.Application() app.SetScriptObject(tg, 0) app.RunScriptString(dm_script) # 解析返回的结果到Python列表 result_tg = app.GetScriptObject() total_count = result_tg.GetTagAsNumber("total_count") tags_info = [] for i in range(total_count): tags_info.append({ "path": result_tg.GetTagAsString(f"{i}_path"), "type_code": result_tg.GetTagAsNumber(f"{i}_type"), "value": result_tg.GetTagAsString(f"{i}_value") }) return tags_info
使用示例:
img = camera.AcquireImage() tg = img.GetTagGroup() all_tags = traverse_tag_group(tg) # 打印所有标签信息 for tag in all_tags: print(f"路径: {tag['path']}, 类型码: {tag['type_code']}, 值: {tag['value']}")
2. 标签的修改、检查操作
同样用原生DM Script调用的思路,可以实现其他常用操作:
检查标签是否存在
def tag_exists(tg, tag_path): dm_script = """ TagGroup tg = GetTagGroupFromScriptObject(0); string path = GetScriptObject(1); SetScriptObject(tg.TagGroupDoesTagExist(path)); """ app = DM.Application() app.SetScriptObject(tg, 0) app.SetScriptObject(tag_path, 1) app.RunScriptString(dm_script) return app.GetScriptObject() == 1
修改标签值(以数字类型为例)
def set_tag_number(tg, tag_path, new_value): dm_script = """ TagGroup tg = GetTagGroupFromScriptObject(0); string path = GetScriptObject(1); number val = GetScriptObject(2); tg.TagGroupSetTagAsNumber(path, val); """ app = DM.Application() app.SetScriptObject(tg, 0) app.SetScriptObject(tag_path, 1) app.SetScriptObject(new_value, 2) app.RunScriptString(dm_script)
补充说明
- 类型码对应关系:可以参考DM Script文档,比如
2=数字、3=字符串、7=TagGroup、4=布尔值等,可根据需求扩展类型处理逻辑。 - 嵌套TagGroup:上面的遍历函数已经处理了嵌套结构,会递归展开所有子标签并返回完整路径。
内容的提问来源于stack exchange,提问作者miile7
相关产品推荐
相关产品推荐

