本文主要是介绍四、官方示例 directconnectdynamicclient (simpleSwitch),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- 1 将replica 添加到项目中
- 2 创建远程节点并将其连接到源主机节点。
- 3 获取远程源对象的副本
- 4 需要注意的点
- 1 只有当Replica发出initialized信号后,该Replica才有Source端的元信息(属性、信号与槽),才能被使用。
- 2 静态 Vs. 动态
- 静态方式的优劣:
动态连接方式实现QtRo
在源端不需要做任何更改,因为动态副本只会影响请求者节点获取副本的方式。因此,我们使用上一章节中所示的源代码。
1 将replica 添加到项目中
因为replica 是动态获取的,所以不需要rep文件。
2 创建远程节点并将其连接到源主机节点。
此步骤的代码与示例1 directconnectclient 中的代码相同
QRemoteObjectNode repNode; // create remote object noderepNode.connectToNode(QUrl(QStringLiteral("local:switch"))); // connect with remote host node
3 获取远程源对象的副本
#include <QCoreApplication>#include "dynamicclient.h"int main(int argc, char *argv[]){QCoreApplication a(argc, argv);QSharedPointer<QRemoteObjectDynamicReplica> ptr; // shared pointer to hold replicaQRemoteObjectNode repNode;repNode.connectToNode(QUrl(QStringLiteral("local:switch")));ptr.reset(repNode.acquireDynamic("SimpleSwitch")); // acquire replica of source from host nodeDynamicClient rswitch(ptr); // create client switch object and pass replica reference to it}
dynamicclient.h
#ifndef _DYNAMICCLIENT_H#define _DYNAMICCLIENT_H#include <QObject>#include <QSharedPointer>#include <QRemoteObjectNode>#include <qremoteobjectdynamicreplica.h>class DynamicClient : public QObject{Q_OBJECTpublic:DynamicClient(QSharedPointer<QRemoteObjectDynamicReplica> ptr);~DynamicClient();Q_SIGNALS:void echoSwitchState(bool switchState);// this signal is connected with server_slot(..) slot of source object and echoes back switch state received from sourcepublic Q_SLOTS:void recSwitchState_slot(); // Slot to receive source statevoid initConnection_slot(); //Slot to connect signals/slot on replica initializationprivate:bool clientSwitchState; // holds received server switch stateQSharedPointer<QRemoteObjectDynamicReplica> reptr;// holds reference to replica};#endif
dynamicclient.cpp
#include "dynamicclient.h"// constructorDynamicClient::DynamicClient(QSharedPointer<QRemoteObjectDynamicReplica> ptr) :QObject(nullptr), reptr(ptr){//connect signal for replica valid changed with signal slot initializationQObject::connect(reptr.data(), SIGNAL(initialized()), this, SLOT(initConnection_slot()));}//destructorDynamicClient::~DynamicClient(){}// Function to initialize connections between slots and signalsvoid DynamicClient::initConnection_slot(){// connect source replica signal currStateChanged() with client's recSwitchState() slot to receive source's current stateQObject::connect(reptr.data(), SIGNAL(currStateChanged()), this, SLOT(recSwitchState_slot()));// connect client's echoSwitchState(..) signal with replica's server_slot(..) to echo back received stateQObject::connect(this, SIGNAL(echoSwitchState(bool)),reptr.data(), SLOT(server_slot(bool)));}void DynamicClient::recSwitchState_slot(){clientSwitchState = reptr->property("currState").toBool(); // use replica property to get currState from sourceqDebug() << "Received source state " << clientSwitchState;Q_EMIT echoSwitchState(clientSwitchState); // Emit signal to echo received state back to server}
4 需要注意的点
1 只有当Replica发出initialized信号后,该Replica才有Source端的元信息(属性、信号与槽),才能被使用。
即我们需要
QObject::connect(reptr.data(), SIGNAL(initialized()), this, SLOT(initConnection_slot()));
收到initialized信号后,才初始化我们的副本端代码(需要用到source信息)
2 静态 Vs. 动态
有了静态和动态两种方式后我们该如何选择呢?在这里我根据自己的实践经验给出一个比较:
静态方式的优劣:
优:
- 拥有明确的定义,更适合在C++中使用(因为有repc生成的头文件)。 支持POD等复杂结构的定义。
- 更高效。因为结构定义都已经在C++中定义好了,不需要动态传输、构建,省去了这方面的开销(其实不大,但多少是有开销的)。
缺:
- Source端和Replica端必须严格使用同一版本的rep文件,即使rep文件内只是添加了一行注释,否则连接不上。这个是我们当时用静态方式最大的痛苦。我们一般将大系统分成多个模块,各模块开发测试通常都是并行的。静态的这个缺点导致我们在测试时经常连接不上。
动态方式的优劣:
优:
- Source端和Replica端不再需要严格使用同一版本的rep文件,因为Replica端已经不需要该文件了,所以Source端随时更改(当然不能改接口定义,不然Replica端肯定没法调用)。
- Source端可以对接口进行版本管理,在兼容旧接口的情况下,动态Replica不需要做任何更新。这个其实是和上面这条联系在一起的。
- 对于QML编程来说使用方法和静态方式是一样的。
缺:
- 在C++端使用起来非常不便。因为没有了repc生成的头文件,所有信号与槽等元信息必须通过Qt的元编程来实现,比较繁琐。
- 不支持POD等复杂结构定义。但我也讲了,可以用QVariantList和QVariantMap两兄弟来曲线救国。
- 必须等初始化后才能使用,给编程增加了额外复杂度,同时增加了构建连接的额外开销。这个是动态这个特性决定的。
这篇关于四、官方示例 directconnectdynamicclient (simpleSwitch)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!