diff options
author | Rainer Keller <Rainer.Keller@qt.io> | 2018-08-27 13:09:59 +0200 |
---|---|---|
committer | Rainer Keller <Rainer.Keller@qt.io> | 2018-09-17 13:43:57 +0000 |
commit | 7a0eca889996309c04aca65a2fceea2a45d1a343 (patch) | |
tree | 09bc7fa6483d3e7c955f85732559b209981c0684 | |
parent | 2f92658d3da7350787985c82a38cbcaf491f5415 (diff) |
qml: Expose method node object node
For easy access to the properties of the function to call the target
node is exposed as node object instead of a string.
Change-Id: I3e5ed1b0f94576221a5eeaca70cd14dbc765377c
Reviewed-by: Jannis Völker <jannis.voelker@basyskom.com>
Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
-rw-r--r-- | examples/opcua/waterpump/waterpump-qml/machine/Machine.qml | 16 | ||||
-rw-r--r-- | src/imports/opcua/opcuamethodnode.cpp | 45 | ||||
-rw-r--r-- | src/imports/opcua/opcuamethodnode.h | 10 | ||||
-rw-r--r-- | src/imports/opcua/opcuanode.cpp | 5 | ||||
-rw-r--r-- | src/imports/opcua/opcuanode.h | 3 | ||||
-rw-r--r-- | src/imports/opcua/plugins.qmltypes | 4 | ||||
-rw-r--r-- | tests/auto/declarative/tst_methodnode.qml | 29 |
7 files changed, 60 insertions, 52 deletions
diff --git a/examples/opcua/waterpump/waterpump-qml/machine/Machine.qml b/examples/opcua/waterpump/waterpump-qml/machine/Machine.qml index 217a3dc..b68a52e 100644 --- a/examples/opcua/waterpump/waterpump-qml/machine/Machine.qml +++ b/examples/opcua/waterpump/waterpump-qml/machine/Machine.qml @@ -70,38 +70,38 @@ Item { } QtOpcUa.MethodNode { - nodeId: machineNodeId - objectNodeId : QtOpcUa.NodeId { + nodeId: QtOpcUa.NodeId { identifier: "s=Machine.Start" ns: "Demo Namespace" } + objectNodeId: machineNodeId id: startMethod } QtOpcUa.MethodNode { - nodeId: machineNodeId - objectNodeId : QtOpcUa.NodeId { + nodeId: QtOpcUa.NodeId { identifier: "s=Machine.Stop" ns: "Demo Namespace" } + objectNodeId: machineNodeId id: stopMethod } QtOpcUa.MethodNode { - nodeId: machineNodeId - objectNodeId : QtOpcUa.NodeId { + nodeId: QtOpcUa.NodeId { identifier: "s=Machine.FlushTank2" ns: "Demo Namespace" } + objectNodeId: machineNodeId id: flushMethod } QtOpcUa.MethodNode { - nodeId: machineNodeId - objectNodeId : QtOpcUa.NodeId { + nodeId: QtOpcUa.NodeId { identifier: "s=Machine.Reset" ns: "Demo Namespace" } + objectNodeId: machineNodeId id: resetMethod } diff --git a/src/imports/opcua/opcuamethodnode.cpp b/src/imports/opcua/opcuamethodnode.cpp index 5ad74fc..bb3037e 100644 --- a/src/imports/opcua/opcuamethodnode.cpp +++ b/src/imports/opcua/opcuamethodnode.cpp @@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE \inherits Node This QML element supports calling method nodes on a server. - The target method node has to be specified by the \l objectNodeId property. + The target object node ID has to be specified by the \l objectNodeId property. \code import QtOpcUa 5.12 as QtOpcUa @@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE ns: "Example Namespace" } objectNodeId : QtOpcUa.NodeId { - identifier: "s=Example.Method" + identifier: "s=Example.Object" ns: "Example Namespace" } connection: myConnection @@ -90,10 +90,10 @@ QT_BEGIN_NAMESPACE */ /*! - \qmlproperty OpcUaNodeId MethodNode::objectNodeId + \qmlproperty OpcUaNode MethodNode::objectNodeId Determines the actual node on which the method is called. - It can be a relative or absolute node ID. + It can be a relative or absolute node Id. */ Q_DECLARE_LOGGING_CATEGORY(QT_OPCUA_PLUGINS_QML) @@ -108,46 +108,37 @@ OpcUaNodeIdType *OpcUaMethodNode::objectNodeId() const return m_objectNodeId; } -void OpcUaMethodNode::setObjectNodeId(OpcUaNodeIdType *nodeId) +void OpcUaMethodNode::setObjectNodeId(OpcUaNodeIdType *node) { - m_objectNodeId = nodeId; - m_objectNodePath.clear(); - emit objectNodeIdChanged(nodeId); + if (m_objectNodeId) + disconnect(m_objectNodeId); - retrieveObjectNodePath(); + m_objectNodeId = node; + connect(m_objectNodeId, &OpcUaNodeIdType::nodeChanged, this, &OpcUaMethodNode::handleObjectNodeIdChanged); + handleObjectNodeIdChanged(); } void OpcUaMethodNode::callMethod() { - if (!m_objectNodeId || !m_node) { - qCWarning(QT_OPCUA_PLUGINS_QML) << "No node or no object ID"; - return; - } - - if (m_objectNodePath.isEmpty()) { - qCWarning(QT_OPCUA_PLUGINS_QML) << "object node path is empty"; + if (!m_objectNode || !m_objectNode->node() || !m_node) { + qCWarning(QT_OPCUA_PLUGINS_QML) << "No node or no object"; return; } - m_node->callMethod(m_objectNodePath, QVector<QOpcUa::TypedVariant> ()); + m_objectNode->node()->callMethod(m_node->nodeId(), QVector<QOpcUa::TypedVariant>()); } -void OpcUaMethodNode::objectNodePathResolved(const QString &str) +void OpcUaMethodNode::handleObjectNodeIdChanged() { - m_objectNodePath = str; + m_objectNode->deleteLater(); + m_objectNode = new OpcUaNode(this); + m_objectNode->setNodeId(m_objectNodeId); + emit objectNodeIdChanged(); } void OpcUaMethodNode::setupNode(const QString &absolutePath) { OpcUaNode::setupNode(absolutePath); - retrieveObjectNodePath(); -} - -void OpcUaMethodNode::retrieveObjectNodePath() -{ - retrieveAbsoluteNodePath(m_objectNodeId, [this](const QString &str) { - this->objectNodePathResolved(str); - }); } QT_END_NAMESPACE diff --git a/src/imports/opcua/opcuamethodnode.h b/src/imports/opcua/opcuamethodnode.h index a79ddd4..255db8e 100644 --- a/src/imports/opcua/opcuamethodnode.h +++ b/src/imports/opcua/opcuamethodnode.h @@ -56,17 +56,17 @@ public slots: void callMethod(); signals: - void objectNodeIdChanged(const OpcUaNodeIdType *nodeId); + void objectNodeIdChanged(); + +private slots: + void handleObjectNodeIdChanged(); private: void setupNode(const QString &absolutePath) override; - void objectNodePathResolved(const QString &); private: - void retrieveObjectNodePath(); - OpcUaNodeIdType *m_objectNodeId = nullptr; - QString m_objectNodePath; // not exposed + OpcUaNode *m_objectNode = nullptr; }; QT_END_NAMESPACE diff --git a/src/imports/opcua/opcuanode.cpp b/src/imports/opcua/opcuanode.cpp index 3c959c7..edefaa3 100644 --- a/src/imports/opcua/opcuanode.cpp +++ b/src/imports/opcua/opcuanode.cpp @@ -293,6 +293,11 @@ const UniversalNode &OpcUaNode::resolvedNode() const return m_resolvedNode; } +QOpcUaNode *OpcUaNode::node() const +{ + return m_node; +} + void OpcUaNode::setAttributesToRead(QOpcUa::NodeAttributes attributes) { m_attributesToRead = attributes; diff --git a/src/imports/opcua/opcuanode.h b/src/imports/opcua/opcuanode.h index 5bc0c28..9148fbf 100644 --- a/src/imports/opcua/opcuanode.h +++ b/src/imports/opcua/opcuanode.h @@ -84,6 +84,9 @@ public: // This function is not exposed to QML const UniversalNode &resolvedNode() const; + // This function is not exposed to QML + QOpcUaNode* node() const; + public slots: void setNodeId(OpcUaNodeIdType *nodeId); void setConnection(OpcUaConnection *); diff --git a/src/imports/opcua/plugins.qmltypes b/src/imports/opcua/plugins.qmltypes index 347519f..2c48221 100644 --- a/src/imports/opcua/plugins.qmltypes +++ b/src/imports/opcua/plugins.qmltypes @@ -49,10 +49,6 @@ Module { exports: ["QtOpcUa/MethodNode 5.12"] exportMetaObjectRevisions: [0] Property { name: "objectNodeId"; type: "OpcUaNodeIdType"; isPointer: true } - Signal { - name: "objectNodeIdChanged" - Parameter { name: "nodeId"; type: "const OpcUaNodeIdType"; isPointer: true } - } Method { name: "setObjectNodeId" Parameter { name: "nodeId"; type: "OpcUaNodeIdType"; isPointer: true } diff --git a/tests/auto/declarative/tst_methodnode.qml b/tests/auto/declarative/tst_methodnode.qml index 40e702c..6b7fda3 100644 --- a/tests/auto/declarative/tst_methodnode.qml +++ b/tests/auto/declarative/tst_methodnode.qml @@ -78,28 +78,41 @@ Item { signalName: "descriptionChanged" } + SignalSpy { + id: node1ObjectNodeIdSpy + target: node1 + signalName: "objectNodeIdChanged" + } + function test_nodeTest() { - compare(node1.browseName, "TestFolder"); - compare(node1.nodeClass, QtOpcUa.Constants.NodeClass.Object); - compare(node1.displayName.text, "TestFolder"); - compare(node1.description.text, ""); + compare(node1.browseName, "multiplyArguments"); + compare(node1.nodeClass, QtOpcUa.Constants.NodeClass.Method); + compare(node1.displayName.text, "ns=3;s=Test.Method.Multiply"); + compare(node1.description.text, "MultiplyDoubles"); + compare(node1.objectNodeId.ns, "Test Namespace"); + compare(node1.objectNodeId.identifier, "s=TestFolder"); compare(node1BrowseNameSpy.count, 1) compare(node1NodeClassSpy.count, 1) compare(node1DisplayNameSpy.count, 1) compare(node1DescriptionSpy.count, 1) + compare(node1ObjectNodeIdSpy.count, 0) + + node1.objectNodeId.identifier = "s=foo"; + node1ObjectNodeIdSpy.wait() + compare(node1ObjectNodeIdSpy.count, 1); } QtOpcUa.MethodNode { connection: connection nodeId: QtOpcUa.NodeId { ns: "Test Namespace" - identifier: "s=TestFolder" - } - objectNodeId: QtOpcUa.NodeId { - ns: "Test Namespace" identifier: "s=Test.Method.Multiply" } + objectNodeId: QtOpcUa.NodeId { + ns: "Test Namespace" + identifier: "s=TestFolder" + } id: node1 } } |