Example 2: Direct Connection with a Dynamic Replica

Describes how the Qt Remote Objects establishes a direct connection with a dynamic replica. .. _qtro-example2: Initially, a dynamic replica is created as a “bare” QObject - without properties, signals or slots. Then, during initialization, QtRO returns the API for the object, after the connection to the source is made. Thus, the API is added to the object at runtime.

There are no changes to be made on the source side, as a dynamic Replica only impacts how the requestor node acquires the replica. So, we use the source-side code shown in Example 1 .

  1. Add replica generation to the project.

    Because the replica is dynamically acquired, no .rep file is required unlike in Example 1 .

  2. Create the remote node and connect it to the source host node.

    The code for this step is unchanged from Example 1 .

    repNode = QRemoteObjectNode()
    repNode.connectToNode(QUrl(QStringLiteral("local:switch"))) # connect with remote host node
    
  3. Acquire a replica of the remote source object.

    In main.cpp, we use a QSharedPointer to hold a replica of the remote object, and then instantiate a replica requestor object:

    from PySide6.QtCore import QCoreApplication
    from dynamicclient import *
    if __name__ == "__main__":
    
        a = QCoreApplication(argc, argv)
    ptr = QSharedPointer()
        repNode = QRemoteObjectNode()
        repNode.connectToNode(QUrl(QStringLiteral("local:switch")))
        ptr.reset(repNode.acquireDynamic("SimpleSwitch")) # acquire replica of source from host node
        rswitch = DynamicClient(ptr)
    

The complete declaration and definition of the requestor class, DynamicClient, is as follows:

dynamicclient.h

#ifndef _DYNAMICCLIENT_H
#define _DYNAMICCLIENT_H
from PySide6.QtCore import QObject

from PySide6.QtRemoteObjects import QRemoteObjectNode

class DynamicClient(QObject):

    Q_OBJECT
# public
    DynamicClient(QSharedPointer<QRemoteObjectDynamicReplica> ptr)
    ~DynamicClient()
Q_SIGNALS:
    def echoSwitchState(server_slot(..):
Q_SLOTS: = public()
    def recSwitchState_slot():
    def initConnection_slot():
# private
    clientSwitchState = bool()
reptr# = QSharedPointer()

#endif

dynamicclient.cpp

from dynamicclient import *
# constructor
def __init__(self, ptr):
    QObject(None), reptr(ptr)

    #connect signal for replica valid changed with signal slot initialization
    QObject.connect(reptr.data(), QRemoteObjectDynamicReplica.initialized, self,
                     DynamicClient::initConnection_slot)

#destructor
DynamicClient::~DynamicClient()


# Function to initialize connections between slots and signals
def initConnection_slot(self):

    # connect source replica signal currStateChanged() with client's recSwitchState() slot to receive source's current state
   QObject.connect(reptr.data(), SIGNAL(currStateChanged()), self, SLOT(recSwitchState_slot()))
   # connect client's echoSwitchState(..) signal with replica's server_slot(..) to echo back received state
   QObject.connect(self, SIGNAL(echoSwitchState(bool)),reptr.data(), SLOT(server_slot(bool)))

def recSwitchState_slot(self):

   clientSwitchState = reptr.property("currState").toBool() # use replica property to get currState from source
   print("Received source state ", clientSwitchState)
   Q_EMIT echoSwitchState(clientSwitchState) # Emit signal to echo received state back to server

When run together with the source-side example, the output is identical to Example 1 .