Qt 5.15中如何获取QOpcUaNode类型属性并正确读取数据类型?
解决QOpcUaNode数据类型读取与写入问题
核心问题原因
你直接调用opcUaNode->attribute(QOpcUa::NodeAttribute::DataType)得到的是该数据类型对应的NodeId(比如UInt16对应ns=0;i=11),而非QOpcUa::Types枚举值,所以无法直接用于写入时的类型指定。而不带类型参数的writeValueAttribute失效,大概率是因为你传入的QVariant类型与节点实际数据类型不匹配,OPC UA服务器会校验类型一致性导致写入失败。
正确读取节点数据类型的步骤
- 读取DataType属性的NodeId
通过同步或异步方式获取节点的DataType属性,得到存储为QOpcUaNodeId的QVariant。 - 将NodeId转换为QOpcUa::Types枚举
调用QOpcUaClient的typeIdFromNodeId()方法,把NodeId转换成对应的类型枚举值。 - 使用转换后的类型进行写入
拿到正确类型后,传入writeValueAttribute方法即可完成适配不同类型节点的写入。
代码示例(同步方式,适用于属性已缓存的场景)
// 获取DataType属性的NodeId QVariant dataTypeVar = opcUaNode->attribute(QOpcUa::NodeAttribute::DataType); if (!dataTypeVar.canConvert<QOpcUaNodeId>()) { // 处理获取失败的情况 return; } QOpcUaNodeId dataTypeId = dataTypeVar.value<QOpcUaNodeId>(); // 转换为QOpcUa::Types枚举 QOpcUa::Types nodeDataType = opcUaNode->client()->typeIdFromNodeId(dataTypeId); if (nodeDataType == QOpcUa::Types::Undefined) { // 无法识别的类型,处理异常 return; } // 执行写入,使用获取到的节点类型 opcUaNode->writeValueAttribute(variant, nodeDataType);
代码示例(异步方式,更可靠,适用于属性未缓存的场景)
如果节点属性尚未从服务器加载,同步获取可能失败,建议用异步读取:
// 异步请求读取DataType属性 opcUaNode->readAttributes(QOpcUa::NodeAttribute::DataType); // 连接属性读取完成的信号 connect(opcUaNode, &QOpcUaNode::attributeRead, this, [=](QOpcUa::NodeAttribute attr, const QVariant& value, QOpcUa::UaStatusCode status) { if (attr != QOpcUa::NodeAttribute::DataType || status != QOpcUa::UaStatusCode::Good) { return; // 读取失败或不是目标属性 } QOpcUaNodeId dataTypeId = value.value<QOpcUaNodeId>(); QOpcUa::Types nodeDataType = opcUaNode->client()->typeIdFromNodeId(dataTypeId); if (nodeDataType != QOpcUa::Types::Undefined) { // 执行写入操作 opcUaNode->writeValueAttribute(variant, nodeDataType); } });
额外提示
如果希望不带类型参数的writeValueAttribute生效,你需要确保传入的QVariant的类型与节点实际数据类型严格一致。比如节点是UInt16,就把QVariant构造为QVariant(static_cast<quint16>(yourValue)),而非默认的int或其他类型。
内容的提问来源于stack exchange,提问作者simgineer
相关产品推荐
相关产品推荐

