Auf dieser Seite

Beispiel 1: Direkte Verbindung über eine statische Quelle

  1. Erstellen eines Quellobjekts

    Um dieses Quellobjekt zu erstellen, erstellen wir zunächst die Definitionsdatei „ simpleswitch.rep “. Diese Datei beschreibt die Eigenschaften und Methoden des Objekts und wird als Eingabe für den „ Qt Remote Objects “-Compiler ( repc) verwendet. Diese Datei definiert lediglich die Schnittstellen, die für die Replikate verfügbar gemacht werden müssen.

    simpleswitch.rep

    class SimpleSwitch
    {
        PROP(bool currState=false);
        SLOT(server_slot(bool clientState));
    };

    In „ simpleswitch.rep “

    • currState wird der aktuelle Zustand des Schalters gespeichert.
    • server_slot() ermöglicht uns die Interaktion mit der Quelle – sie wird mit dem Signal „ echoSwitchState(bool newstate) “ verbunden.

    Damit repc diese Datei verarbeiten kann, fügen Sie die folgende Zeile in Ihre Datei „ cmake “ ein:

    qt6_add_repc_sources(directconnectserver
        simpleswitch.rep
    )

    Wenn Sie „ qmake “ verwenden:

    REPC_SOURCE = simpleswitch.rep

    Diese Anleitung gilt nur für das Qt Remote Objects-Modul, daher müssen Sie dieses ebenfalls zu Ihrem Projekt hinzufügen. Wenn Sie CMake verwenden, fügen Sie Folgendes hinzu:

    find_package(Qt6 REQUIRED COMPONENTS RemoteObjects)
    target_link_libraries(directconnectserver PRIVATE Qt6::RemoteObjects)

    Wenn Sie „ qmake “ verwenden:

    QT       += remoteobjects

    repc erstellt die Header-Datei „ rep_SimpleSwitch_source.h “ in dem von Ihnen angegebenen Build-Verzeichnis. Weitere Informationen finden Sie unter „Source“.

    repc erstellt drei Hilfsklassen für die Verwendung mit QtRO. In diesem Beispiel verwenden wir die Basisklasse „ SimpleSwitchSimpleSource “. Es handelt sich um eine abstrakte Klasse, die in „ rep_SimpleSwitch_source.h “ definiert ist. Wir leiten unsere Implementierungsklasse „SimpleSwitch“ wie unten gezeigt von dieser Klasse ab:

    simpleswitch.h

    #ifndef SIMPLESWITCH_H
    #define SIMPLESWITCH_H
    
    #include "rep_simpleswitch_source.h"
    
    class SimpleSwitch : public SimpleSwitchSimpleSource
    {
        Q_OBJECT
    public:
        SimpleSwitch(QObject *parent = nullptr);
        ~SimpleSwitch();
        void server_slot(bool clientState) override;
    public Q_SLOTS:
        void timeout_slot();
    private:
        QTimer *stateChangeTimer;
    };
    
    #endif

    In simpleswitch.h,

    • stateChangeTimer gibt es ein „ QTimer “, das dazu dient, den Zustand unseres „SimpleSwitch“ umzuschalten.
    • timeout_slot() ist mit dem Signal „timeout()“ von „ stateChangeTimer “ verbunden.
    • server_slot() – das automatisch an der Quelle aufgerufen wird, sobald eine Replik ihre Version des Slots aufruft – gibt den empfangenen Wert aus.
    • currStateChanged(bool), definiert in dem von repc generierten „ rep_SimpleSwitch_source.h “, wird immer dann ausgesendet, wenn „ currState “ umschaltet. In diesem Beispiel ignorieren wir das Signal auf der Quellseite und verarbeiten es später auf der Replikseite.

    Die Definition unserer Klasse ` SimpleSwitch ` ist unten aufgeführt:

    simpleswitch.cpp

    #include "simpleswitch.h"
    
    // Konstruktor
    SimpleSwitch::SimpleSwitch(QObject*parent) : SimpleSwitchSimpleSource(parent)
    {
        stateChangeTimer = new QTimer(this); // Timer initialisieren
        QObject::connect(stateChangeTimer, &QTimer::timeout, this, &SimpleSwitch::timeout_slot); // Signal „timeout()“ von stateChangeTimer mit „timeout_slot()“ von simpleSwitch verbinden
        stateChangeTimer->start(2000); // Timer starten und Timeout auf 2 Sekunden setzen
        qDebug() << "Source Node Started";
    }
    
    // Destruktor
    SimpleSwitch::~SimpleSwitch()
    {
        stateChangeTimer->stop();
    }
    
    void SimpleSwitch::server_slot(bool clientState)
    {
        qDebug() << "Replica state is " << clientState; // print switch state echoed back by client
    }
    
    void SimpleSwitch::timeout_slot()
    {
        // Slot wird bei Ablauf des Timers aufgerufen
        if (currState()) // Prüfen, ob der aktuelle Zustand „true“ ist; currState() ist in der von REPC generierten Datei „rep_simpleswitch_source.h“ definiert
            setCurrState(false); // Zustand auf „false“ setzen
        else
            setCurrState(true); // Zustand auf „true“ setzen
        qDebug() << "Source State is "<<currState();
    
    }
  2. Registrierung erstellen

    Da in diesem Beispiel eine direkte Verbindung zwischen den Knoten verwendet wird, können wir diesen Schritt überspringen.

  3. Erstellen eines

    Host-Knotens Der Host-Knoten wird wie folgt erstellt:

    QRemoteObjectHost srcNode(QUrl(QStringLiteral("local:replica")));
  4. Host-Source-Objekt und

    Remoting Die folgenden Anweisungen instanziieren das Source -Objekt und übergeben es an den Host, um „Remoting“ zu ermöglichen – also den Vorgang, bei dem ein Objekt für das QtRO-Netzwerk sichtbar gemacht wird:

    SimpleSwitch srcSwitch; // create simple switch
    srcNode.enableRemoting(&srcSwitch); // enable remoting

    Der Inhalt der Datei „ main.cpp “, die die oben beschriebenen Schritte implementiert, lautet wie folgt:

    main.cpp

    #include <QCoreApplication>
    #include "simpleswitch.h"
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        SimpleSwitch srcSwitch; // create simple switch
    
        // Create host node without Registry:
        QRemoteObjectHost srcNode(QUrl(QStringLiteral("local:replica")));
        srcNode.enableRemoting(&srcSwitch); // enable remoting/sharing
    
        return a.exec();
    }

    Kompilieren und führen Sie dieses quellseitige Projekt aus. Die Ausgabe sollte – ohne dass Replikate erstellt wurden – wie unten dargestellt aussehen, wobei der Switch-Zustand alle zwei Sekunden zwischen „ true “ und „ false “ wechselt.

    Beispiel 1: Serverausgabe

  • Die folgenden Schritte dienen der Erstellung der Replikationsseite des Netzwerks, die in diesem Beispiel den Status des Switches von der Quelle abruft und ihn zurückgibt.

    Replik-Code

    1. Verwenden Sie „repc“, um Ihrem

      Projekt

      eine Replik hinzuzufügen

      . Wir verwenden dieselbe API-Definitionsdatei wie auf der Quellseite, SimpleSwitch.rep, um mit „repc“ eine Replik-Header-Datei zu erstellen. Wenn Sie cmake verwenden, fügen Sie die folgende Zeile in Ihre clientseitige Datei „ cmake “ ein und geben Sie dabei die Datei „ .rep “ als Eingabe an:

      qt6_add_repc_replicas(directconnectclient
          simpleswitch.rep
      )

      Wenn Sie qmake verwenden, fügen Sie die folgende Zeile in Ihre clientseitige Datei „ .pro “ ein:

      REPC_REPLICA = simpleswitch.rep

      Das repc -Tool generiert eine „ rep_SimpleSwitch_replica.h “-Datei im Build-Verzeichnis. Weitere Informationen finden Sie unter „Replica“.

    2. Erstellen Sie einen Knoten, um eine Verbindung zum

      Host-Knoten

      der Quelle herzustellen

      . Der folgende Code instanziiert den zweiten Knoten im Netzwerk und verbindet ihn mit dem Host-Knoten der Quelle:

      QRemoteObjectNode repNode; // create remote object node
      repNode.connectToNode(QUrl(QStringLiteral("local:replica"))); // connect with remote host node
    3. Rufen Sie die Methode ` acquire()` des Knotens auf, um einen Zeiger auf eine Replik zu erstellen

      Zunächst instanziieren wir eine Replik:

      QSharedPointer<SimpleSwitchReplica> ptr;
      ptr.reset(repNode.acquire<SimpleSwitchReplica>()); // acquire replica of source from host node

      Hinweis: ` acquire()` gibt einen Zeiger auf die Replik zurück, verwaltet jedoch nicht deren Lebensdauer. Dieses Beispiel zeigt die empfohlene Vorgehensweise, den zurückgegebenen Zeiger in eine ` QSharedPointer ` oder ` QScopedPointer ` zu verpacken, um sicherzustellen, dass der Zeiger stets ordnungsgemäß gelöscht wird.

      main.cpp setzt die oben beschriebenen Schritte um und instanziiert unser Objekt:

      main.cpp

      #include <QCoreApplication>
      #include "client.h"
      
      int main(int argc, char *argv[])
      {
          QCoreApplication a(argc, argv);
      
          QSharedPointer<SimpleSwitchReplica> ptr; // shared pointer to hold source replica
      
          QRemoteObjectNode repNode; // create remote object node
          repNode.connectToNode(QUrl(QStringLiteral("local:replica"))); // connect with remote host node
      
          ptr.reset(repNode.acquire<SimpleSwitchReplica>()); // acquire replica of source from host node
      
          Client rswitch(ptr); // create client switch object and pass reference of replica to it
      
          return a.exec();
      }

      Die vollständige Deklaration und Definition der Klasse „ Client “ lautet wie folgt:

      client.h

      #ifndef _CLIENT_H
      #define _CLIENT_H
      
      #include <QObject>
      #include <QSharedPointer>
      
      #include "rep_simpleswitch_replica.h"
      
      class Client : public QObject
      {
          Q_OBJECT
      public:
          Client(QSharedPointer<SimpleSwitchReplica> ptr);
          ~Client() override = default;
          void initConnections();// Function to connect signals and slots of source and client
      
      Q_SIGNALS:
          void echoSwitchState(bool switchState);// this signal is connected with server_slot(..) on the source object and echoes back switch state received from source
      
      public Q_SLOTS:
          void recSwitchState_slot(bool); // slot to receive source state
      private:
          bool clientSwitchState; // holds received server switch state
          QSharedPointer<SimpleSwitchReplica> reptr;// holds reference to replica
      
       };
      
      #endif

      client.cpp

      #include "client.h"
      
      // Konstruktor
      Client::Client(QSharedPointer<SimpleSwitchReplica> ptr) :
          QObject(nullptr),reptr(ptr)
      {
          // Signalverbindung für die Replik, die mit dem Initialisierungs-Slot initialisiert wurde.
          initConnections();
          // Wir können eine Verbindung zu den Signalen/Slots von SimpleSwitchReplica
          // direkt  herstellen , da unsere Replik von repc generiert wurde.
      }
      
      void Client::initConnections()
      {
          // Verbindungen zwischen Signalen und Slots initialisieren
      
          // Das Signal „currStateChanged()“ der Quell-Replik mit dem Slot „recSwitchState()“ des Clients verbinden, um den aktuellen Zustand der Quelle zu empfangen
          QObject::connect(reptr.data(), &SimpleSwitchReplica::currStateChanged, this, &Client::recSwitchState_slot);
          // Verbinde das Signal `echoSwitchState(..)` des Clients mit dem `server_slot(..)` der Replik, um den empfangenen Zustand zurückzusenden
          QObject::connect(this, &Client::echoSwitchState, reptr.data(), &SimpleSwitchReplica::server_slot);
      }
      
      void Client::recSwitchState_slot(bool value)
      {
          qDebug() << "Received source state "<< value << reptr.data()->currState();
          clientSwitchState = reptr.data()->currState();
          Q_EMIT echoSwitchState(clientSwitchState); // Signal senden, um den empfangenen Zustand an den Server zurückzusenden
      }

      Das Kompilieren und Ausführen dieses Beispiels zusammen mit dem Beispiel auf der Quellseite erzeugt die folgende Ausgabe:

      Ausgabe der Direct Connect-Server-Client-Kommunikation

    © 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.