Logs
Consultez les logs.
OK
Liste des données
Consultez la liste des données.
OK
Loading...
Formulaire
Saisissez vos données.
Enregistrer
Annuler

Références DDS

Vues
142

DDS (Data Distribution Service) est un middleware réseau qui simplifie la programmation réseau complexe. Il implémente un modèle de publication-abonnement pour l'envoi et la réception de données, d'événements et de commandes entre les noeuds. Les noeuds producteurs d'informations (éditeurs) créent des « sujets » (par exemple, température, localisation, pression) et publient des « échantillons ».

Dans ce tutoriel, vous apprendrez à communiquer des données à travers le réseau DDS fournit par la librairie RTI Context dans un environnement C++ interfacé avec la librairie Qt/QML



Opérations sur les définitions



Protocole DDS (Data Distribution Service)


DDS (Data Distribution Service) est un middleware réseau qui simplifie la programmation réseau complexe. Il implémente un modèle de publication-abonnement pour l'envoi et la réception de données, d'événements et de commandes entre les noeuds. Les noeuds producteurs d'informations (éditeurs) créent des « sujets » (par exemple, température, localisation, pression) et publient des « échantillons ». 

Entreprise RTI (Real-Time Innovations)


RTI (Real-Time Innovations) est l'éditeur de frameworks logiciels pour systèmes d'IA physique, dont la mission est de contribuer à un monde plus intelligent. RTI est le seul à allier des décennies d'expertise technique à des logiciels et outils de pointe pour développer des systèmes plus intelligents, plus rapidement. 

RTI Connext fournit l'architecture de données de plus de 2 000 conceptions dans les secteurs de l'aérospatiale et de la défense, des technologies médicales, de l'automobile et de la robotique. 

Le logiciel RTI :

Présent dans plus d'un million de véhicules en circulation aujourd'hui,
Prend en charge des dizaines d'ADAS automobiles et d'architectures logicielles,
Permet le fonctionnement des systèmes les plus critiques au monde,
Contrôle les plus grandes centrales électriques d'Amérique du Nord,
Intègre plus de 400 programmes de défense majeurs,
Génère une nouvelle génération de systèmes MedTech et de robotique,
Est utilisé par 6 des 10 plus grandes entreprises de dispositifs médicaux,
Sous-tend les systèmes de contrôle du trafic aérien du Canada et les systèmes de contrôle de lancement de la NASA.

RTI est le principal fournisseur de produits conformes à la norme DDS (Data Distribution Service).

Contexte RTI (RTI Context DDS)


image.png

RTI Connext DDS est un framework de connectivité permettant de créer des applications distribuées exigeant des performances et une évolutivité élevées. Il comprend les composants suivants :

Un SDK qui fournit des API pour vous aider à envoyer et recevoir des données selon les modèles de communication décrits dans cette documentation (voir Étapes suivantes). Ces API vous permettent de connecter vos propres applications à d'autres applications sur le bus de données.
Des outils qui vous aident à visualiser vos données et à déboguer votre système distribué.
Services d'infrastructure pouvant exécuter des fonctions dédiées dans votre système, telles que l'enregistrement, le pontage et la persistance des données.

Qualité de service QoS (Quality of Service)


QoS est un ensemble de technologies qui fonctionnent sur un réseau pour garantir sa capacité à exécuter de manière fiable des applications et du trafic prioritaires malgré une capacité réseau limitée. Les technologies QoS y parviennent en fournissant une gestion et une allocation de capacité différenciées à des flux spécifiques du trafic réseau. 

image.png

DDS se présente sous forme d'une couche logicielle dite intergicielle (middleware) dont la fonction principale est d'offrir une technologie d'échanges de données typées, classifiées par sujet (topics) tout en respectant une panoplie de qualités de services (QoS) négociées entre les producteurs de la donnée et ses consommateurs.




Opérations sur la licence d'utilisation



Configuration de la licence d'utilisation


La plupart des installations nécessitent un fichier de licence pour exécuter les outils ou fonctionnalités de la plateforme Connext. Si votre distribution nécessite un fichier de licence, vous en recevrez un de RTI par e-mail.

Email de réception de la licence :

Merci de votre intérêt pour Connext. Nous sommes ravis de vous accompagner dans la découverte de toutes ses fonctionnalités. Vous trouverez ci-joint votre clé d'activation de 14 jours pour RTI Connext afin de démarrer. Que se passe-t-il après 14 jours ? Vous bénéficierez d'un accès illimité à notre version gratuite, Connext Express, conçue pour les petits systèmes.

image.png

image.png

Le moyen le plus simple de configurer de manière permanente votre fichier de licence est d'utiliser Launcher , comme indiqué ci-dessous :

image.png

image.png

image.png

image.png

Si vous ne souhaitez pas utiliser Launcher, vous pouvez également installer une licence en la plaçant dans l'un de ces deux emplacements :

image.png

Une troisième façon d'installer une licence consiste à configurer la variable d'environnement RTI_LICENSE_FILE pour qu'elle pointe vers votre fichier de licence.

Limitation de la licence d'évaluation


J'ai rencontré le problème suivant lors de l'exécution de l'exemple « Hello World » présenté dans la documentation de RTI Connext. Il semble que l'erreur soit due à un problème de licence. Cependant, comme vous pouvez le constaté précédemment, j'ai correctement lié ma licence via le lanceur RTI Launcher et il l'a reconnu.

image.png

Vous pouvez déclencher cette erreur, par exemple, lors de l'utilisation d'une licence « eval ». Avec ce type de licence, une vérification de licence d'exécution est effectuée sur les applications. Cette vérification est différente de celle effectuée par RTI Launcher. Ainsi, même si votre licence est correctement enregistrée dans RTI Launcher, cet enregistrement ne sera pas valide lors de l'exécution de vos applications utilisateur. Dans ce cas, l'appel de l'application à (DomainParticipantFactory.create_participant) renverra null, empêchant ainsi la communication.

Utilisation de la licence d'évaluation


L'erreur « Service de distribution de données RTI : aucune source pour les informations de licence » se produit aussi lorsque le fichier de licence est introuvable ou que la licence a expiré. Dans ce cas, l'application utilisateur ne pourra pas initialiser Connext DDS, selon les termes de la licence.

Pour éviter ce problème, configurez votre environnement pour permettre aux applications de trouver le fichier de licence. À chaque démarrage, une application recherche un fichier de licence aux emplacements suivants jusqu'à ce qu'elle trouve une licence valide :

Dans la propriété PropertyQosPolicy du DomainParticipant , il peut y avoir une propriété appelée dds.license.license_string. Vous pouvez définir cette propriété soit dans le code source, soit dans un fichier XML, par exemple :

image.png

Dans la propriété PropertyQosPolicy du DomainParticipant, il peut y avoir une propriété appelée dds.license.license_file. Vous pouvez définir cette propriété soit dans le code source, soit dans un fichier XML, par exemple :

image.png

À l'emplacement spécifié dans la variable d'environnement RTI_LICENSE_FILE, que vous pouvez définir pour pointer vers le chemin complet du fichier de licence, y compris le nom du fichier, par exemple, « C:\my_licenses\rti_license.dat ». 

image.png

image.png

image.png


Opérations sur l'application (rdvDDS)



Configuration du nom de l'émetteur


Pour configurer le nom de l'émetteur DDS :

On sélectionne l'onglet (1, Settings).
On édite le nom de l'émetteur DDS (2, You).
On configure le nom de l'émetteur DDS (3, Set Chat Name).

image.png

Publication d'un message DDS


Pour publier un message DDS :

On sélectionne l'onglet (1, Message).
On édite le message DDS (2, Bonjour tout le monde !).
On publie le message DDS (3, Publish Message to DDS).
On affiche le message reçu du serveur DDS (4, Me: Bonjour tout le monde !).

image.png

Diagramme des flux d'informations


image.png

Diagramme des classes mises en jeu


image.png


Opérations sur le programme (C++)



Opérations sur le programme principal (main.cpp)



Opérations sur le programme principal (main)


Dans le programme principal (main) :

On enregistre le module (QrtiDDShandler) dans le contexte QML.
On charge la fenêtre principale (Main.qml).

...
int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QGuiApplication::setApplicationName("rdv.dds");
    QGuiApplication::setApplicationDisplayName("rdvDDS");
    QGuiApplication::setApplicationVersion("1.0.0");
    QGuiApplication::setWindowIcon(QIcon(":/img/logo.png"));

    qmlRegisterType<QrtiDDShandler>("org.QrtiDDS", 1, 0, "QrtiDDShandler");

    QQmlApplicationEngine engine;
    QObject::connect(
        &engine,
        &QQmlApplicationEngine::objectCreationFailed,
        &app,
        []() { QCoreApplication::exit(-1); },
        Qt::QueuedConnection);
    engine.loadFromModule("rdv.dds", "Main");

    return app.exec();
}
...

Opérations sur le module (QrtiDDShandler)



Dans la déclaration du module (QrtiDDShandler) :

On déclare le module (QrtiDDShandler) en tant que dérivé de la classe (QObject).
On crée la propriété (dataAccess) avec la méthode d'écriture (writeData) avec la méthode de lecture (readData) avec la méthode de notification (newRcvdDataAvailable).

...
class QrtiDDShandler : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString dataAccess WRITE writeData READ readData NOTIFY newRcvdDataAvailable)

    void setUp_rtiDDS_handler();
public:
    explicit QrtiDDShandler(QObject *parent = 0);
    ~QrtiDDShandler();

    QString readData();

signals:
    void newRcvdDataAvailable(QString data);
    void newSendDataAvailable(QString data);
public slots:
    void writeData(QString data);
    void readListenerData(QString data);

private:
    QrtiDDS              * rtiDDS;
    QrtiDDSlistener      * rtiDDSlistener;
    QString              rtiDDSrcvBuffer;
};
...

Opérations sur le constructeur (QrtiDDShandler)


Dans le constructeur (QrtiDDShandler) :

On exécute la méthode (setUp_rtiDDS_handler) du module (QrtiDDShandler).

...
QrtiDDShandler::QrtiDDShandler(QObject *parent)
    : QObject(parent)
{
    setUp_rtiDDS_handler();
}
...

Opérations sur la méthode (setUp_rtiDDS_handler)


Dans la méthode (setUp_rtiDDS_handler) :

On construit le module (rtiDDSlistener) de type (QrtiDDSlistener).
On construit le module (rtiDDS) de type (QrtiDDS).
On connecte le signal (newData) du module (QrtiDDSlistener) au slot (readListenerData) du module (QrtiDDShandler). 

...
void QrtiDDShandler::setUp_rtiDDS_handler()
{
    rtiDDSlistener = new QrtiDDSlistener(this);
    rtiDDS = new QrtiDDS(this, rtiDDSlistener);
    connect(rtiDDSlistener, SIGNAL(newData(QString)),
            this, SLOT(readListenerData(QString)),
            Qt::QueuedConnection);
}
...

Opérations sur la méthode (writeData)


Dans la méthode (writeData) :

On émet le signal (newSendDataAvailable) du module (QrtiDDShandler).

...
void QrtiDDShandler::writeData(QString data){
    emit newSendDataAvailable(data);
}
...

Opérations sur la méthode (readData)


Dans la méthode (readData) :

On exécute la variable (rtiDDSrcvBuffer) du module (QrtiDDShandler).

...
QString QrtiDDShandler::readData(){
    return rtiDDSrcvBuffer;
}
...

Opérations sur la méthode (readListenerData)


Dans la méthode (readListenerData) :

On met à jour la variable (rtiDDSrcvBuffer) du module (QrtiDDShandler).
On émet le signal (newSendDataAvailable) du module (QrtiDDShandler).

...
void QrtiDDShandler::readListenerData(QString data) {
    qDebug()<<__FUNCTION__<<__LINE__  << this << "recieved: " << data;
    rtiDDSrcvBuffer = data;
    emit newRcvdDataAvailable(data);
}
...

Opérations sur le module (QrtiDDSlistener)



Dans la déclaration du module (QrtiDDSlistener) :

On déclare le module (QrtiDDSlistener) en tant que dérivé des classe (QObject, DDSDataReaderListener).

...
class QrtiDDSlistener : public QObject, public DDSDataReaderListener
{
    Q_OBJECT
public:
    explicit QrtiDDSlistener(QObject *parent);

signals:
    void newData(QString data);

private:
    void on_data_available(DDSDataReader *reader);
};
...

Opérations sur le constructeur (QrtiDDSlistener)


Dans le constructeur (QrtiDDSlistener) :

On ne fait rien.

...
QrtiDDSlistener::QrtiDDSlistener(QObject *parent) 
    : QObject(parent)
{}
...

Opérations sur la méthode (on_data_available)


Dans la méthode (on_data_available) :

On rentre dans une boucle infinie.
On exécute la méthode (take_next_sample) du module (string_reader) de type (DDSStringDataReader) pour retourner le code (retcode) de type (DDS_ReturnCode_t).
On casse la boucle si le code (retcode) de type (DDS_ReturnCode_t) est égale à (DDS_RETCODE_NO_DATA).
On retourne de la méthode si le code (retcode) de type (DDS_ReturnCode_t) est différent de (DDS_RETCODE_OK).
On émet le signal (newData) du module (QrtiDDSlistener) si la variable (valid_data) de l'objet (info) de type (DDS_SampleInfo) est (Vraie).

...
void QrtiDDSlistener::on_data_available(DDSDataReader *reader) {
    DDSStringDataReader * string_reader = NULL;
    char                  sample[MAX_STRING_SIZE];
    DDS_SampleInfo        info;
    DDS_ReturnCode_t      retcode;

    /* Perform a safe type-cast from a generic data reader into a
     * specific data reader for the type "DDS::String"
     */
    string_reader = DDSStringDataReader::narrow(reader);
    if (string_reader == NULL) {
        /* In this specific case, this will never fail */
        qDebug()<<__FUNCTION__<<__LINE__  << "DDSStringDataReader::narrow failed.";
        return;
    }

    /* Loop until there are messages available in the queue */
    char *ptr_sample = &sample[0];
    for(;;) {
        retcode = string_reader->take_next_sample(
            ptr_sample,
            info);
        if (retcode == DDS_RETCODE_NO_DATA) {
            /* No more samples */
            break;
        } else if (retcode != DDS_RETCODE_OK) {
            qDebug()<<__FUNCTION__<<__LINE__  << "Unable to take data from data reader, error " << retcode;
            return;
        }
        if (info.valid_data) {
            // Valid (this isn't just a lifecycle sample): print it

            emit newData(sample);

            if(strlen(sample) == 0){
                shutdown_flag = DDS_BOOLEAN_TRUE;
            }
        }
    }
}
...

Opérations sur le module (QrtiDDS)



Dans la déclaration du module (QrtiDDS) :

On déclare le module (QrtiDDS) en tant que dérivé de la classe (QObject).

...
class QrtiDDS : public QObject
{
    Q_OBJECT
public:
    explicit QrtiDDS(QObject *parent, QrtiDDSlistener *rtiDDSlistener);
    ~QrtiDDS();

    DDSDomainParticipant *  participant;
    DDSTopic *              topic;
    DDSDataWriter *         data_writer;
    DDSDataReader *         data_reader;
    DDSStringDataWriter *   string_writer;
    DDS_ReturnCode_t        retcode;
    QrtiDDSlistener *         rtiDDSlistener;
    char                    sample[MAX_STRING_SIZE];
    int                     main_result;

public slots:
    void publishDDS(QString data);

private:
    int setupQrtiDDS();
};
...

Opérations sur le constructeur (QrtiDDS)


Dans le constructeur (QrtiDDS) :

On exécute la méthode (setupQrtiDDS) du module (QrtiDDS).

...
QrtiDDS::QrtiDDS(QObject *parent, QrtiDDSlistener *listener)
    : QObject(parent)
{
    DDSDomainParticipant *  participant = NULL;
    DDSTopic *              topic = NULL;
    DDSDataWriter *         data_writer = NULL;
    DDSDataReader *         data_reader = NULL;
    DDSStringDataWriter *   string_writer = NULL;

    rtiDDSlistener = listener;

    int success = setupQrtiDDS();
    if (success != 0)
    {
        qDebug()<<__FUNCTION__<<__LINE__  << "Couldn't setup DDS Objects";
    }
}
...

Opérations sur la méthode (setupQrtiDDS)


Dans la méthode (setupQrtiDDS) :

On exécute la méthode (create_participant) du module (DDSDomainParticipantFactory) pour construire le module (participant) de type (DDSDomainParticipant).
On exécute la méthode (create_topic) du module (participant) de type (DDSDomainParticipant) pour construire le module (topic) de type (DDSTopic).
On exécute la méthode (create_datawriter) du module (participant) de type (DDSDomainParticipant) pour construire le module (data_writer) de type (DDSDataWriter).
On exécute la méthode (create_datareader) du module (participant) de type (DDSDomainParticipant) pour construire le module (data_reader) de type (DDSDataReader).
On exécute la méthode (narrow) du module (DDSStringDataWriter) pour construire le module (string_writer) de type (DDSStringDataWriter).
On connecte le signal (newSendDataAvailable) du module (QrtiDDShandler) au slot (publishDDS) du module (QrtiDDS).

...
int QrtiDDS::setupQrtiDDS()
{
    participant = DDSDomainParticipantFactory::get_instance()->
                  create_participant(
                      0,                              /* Domain ID */
                      DDS_PARTICIPANT_QOS_DEFAULT,    /* QoS */
                      NULL,                           /* Listener */
                      DDS_STATUS_MASK_NONE);
    if (participant == NULL) {
        qDebug()<<__FUNCTION__<<__LINE__  << "Unable to create domain participant.";
        return 1;
    }

    /* Create the topic "Hello, World" for the String type */
    topic = participant->create_topic(
        "Qt rti DDS",                          /* Topic name*/
        DDSStringTypeSupport::get_type_name(), /* Type name */
        DDS_TOPIC_QOS_DEFAULT,                 /* Topic QoS */
        NULL,                                  /* Listener  */
        DDS_STATUS_MASK_NONE);
    if (topic == NULL) {
        qDebug()<<__FUNCTION__<<__LINE__  << "Unable to create topic." ;
        return 1;
    }

    /* Create the data writer using the default publisher */
    data_writer = participant->create_datawriter(
        topic,
        DDS_DATAWRITER_QOS_DEFAULT,     /* QoS */
        NULL,                           /* Listener */
        DDS_STATUS_MASK_NONE);
    if (data_writer == NULL) {
        qDebug()<<__FUNCTION__<<__LINE__ << "Unable to create data writer.";
        return 1;
    }

    data_reader = participant->create_datareader(
        topic,
        DDS_DATAREADER_QOS_DEFAULT,    /* QoS */
        rtiDDSlistener,                      /* Listener */
        DDS_DATA_AVAILABLE_STATUS);
    if (data_reader == NULL) {
        qDebug()<<__FUNCTION__<<__LINE__  << "Unable to create data reader.";
        return 1;
    }

    string_writer = DDSStringDataWriter::narrow(data_writer);
    if (string_writer == NULL) {
        /* In this specific case, this will never fail */
        qDebug()<<__FUNCTION__<<__LINE__  << "DDS_StringDataWriter_narrow failed.";
    }
    connect(parent(), SIGNAL(newSendDataAvailable(QString)), this, SLOT(publishDDS(QString)));

    return 0;
}
...

Opérations sur la méthode (publishDDS)


Dans la méthode (publishDDS) :

On exécute la méthode (write) du module (string_writer) de type (DDSStringDataWriter).

...
void QrtiDDS::publishDDS(QString data){
    string_writer->write(data.toUtf8().constData(), DDS_HANDLE_NIL);
    qDebug()<<__FUNCTION__<<__LINE__  << this << "sent: " << data;
}
...


Opérations sur le programme (QML)



Opérations sur la fenêtre principale (Main.qml)



Opérations sur le programme (Main.qml)


...
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Dialogs
import org.QrtiDDS 1.0

ApplicationWindow {
    id: root
    title: qsTr("rdvDDS")
    minimumHeight: 300
    minimumWidth: 400

    maximumWidth: Screen.width
    maximumHeight: Screen.height
    visible: true

    property string myName : "thurberdog"
    property variant mySettingsWindow

    menuBar: MenuBar {
        Menu {
            title: qsTr("&File")
            MenuItem {
                text: qsTr("E&xit")
                onTriggered: Qt.quit();
            }
        }
    }

    TabBar {
        id: myTabs
        width: parent.width

        TabButton {
            text: "Message"
        }

        TabButton {
            text: "Settings"
        }
    }

    StackLayout {
        anchors.top: myTabs.bottom
        anchors.bottom: parent.bottom
        width: parent.width
        currentIndex: myTabs.currentIndex

        Item {
            id: messageTab

            ColumnLayout {
                anchors.fill: parent
                anchors.margins: 10
                spacing: 10

                TextArea {
                    id: rcvMsgs
                    readOnly: true
                    Layout.fillHeight: true
                    Layout.fillWidth: true
                }

                TextField {
                    id: publish_message
                    text: ""
                    Layout.fillWidth: true
                    onAccepted: {
                        if (text){
                            msgHandler.writeData(root.myName + ": " + text);
                            publish_message.text = "";
                        }
                    }
                }

                Button {
                    id: publish_messageBtn
                    text: "Publish Message to DDS"
                    Layout.fillWidth: true
                    onClicked: {
                        if (publish_message.text){
                            msgHandler.writeData(root.myName + ": " + 
                            publish_message.text);
                            publish_message.text = "";
                        }
                    }
                }

                QrtiDDShandler{
                    id: msgHandler
                    onNewRcvdDataAvailable: rcvMsgs.append(data);
                }
            }
        }

        Item {
            id: settingsTab

            ColumnLayout {
                anchors.fill: parent
                anchors.margins: 10
                spacing: 10

                TextField {
                    id: myName
                    text: root.myName
                    Layout.fillWidth: true
                    rightPadding: 10
                    leftPadding: 10

                    onAccepted: {
                        if (text){
                            root.myName = text;
                            messageDialog.show(qsTr("Name successfully 
                            changed"))
                        }
                    }
                }

                Button{
                    id: setName
                    text: "Set Chat Name"
                    Layout.fillWidth: true

                    onClicked: {
                        if (myName.text){
                            root.myName = myName.text
                            messageDialog.show(qsTr("Name successfully 
                            changed"))
                        }
                    }
                }

                Item {
                    Layout.fillHeight: true
                }

                MessageDialog {
                    id: messageDialog
                    title: qsTr("Successful")

                    function show(caption) {
                        messageDialog.text = caption;
                        messageDialog.open();
                    }
                }
            }
        }
    }
}
...

Opérations sur la fenêtre principale (ApplicationWindow)


Dans la fenêtre principale (ApplicationWindow) :

On crée la propriété (id, root).
On crée le composant (menuBar, MenuBar).
On crée le composant (TabBar).
On crée le composant (StackLayout).

Opérations sur le composant (menuBar, MenuBar)


Dans le composant (menuBar, MenuBar) :

On crée le composant (Menu, title, File)
On crée le composant (MenuItem, text, Exit).
On connecte le signal (onTriggered) du composant (MenuItem, text, Exit) à la méthode (quit) du composant (ApplicationWindow).

Opérations sur le composant (TabBar)


Dans le composant (TabBar) :

On crée la propriété (id, myTab)
On crée le composant (TabButton, text, Message)
On crée le composant (TabButton, text, Settings)

Opérations sur le composant (StackLayout)


Dans le composant (StackLayout) :

On crée la propriété (currentIndex, myTabs.currentIndex)
On crée le composant (Item, id, messageTab)
On crée le composant (Item, id, settingsTab)

Opérations sur le composant (Item, id, messageTab)


Dans le composant (Item, id, messageTab) :

On crée le composant (ColumnLayout).
On ajoute le composant (TextArea, id, rcvMsg).
On ajoute le composant (TextField, id, publish_message).
On ajoute le composant (Button, id, publish_messageBtn).
On ajoute le composant (QrtiDDShandler, id, msgHandler).

Opérations sur le composant (TextField, id, publish_message)


Dans le composant (TextField, id, publish_message) :

On connecte le signal (onAccepted) à la méthode (onAccepted, publish_message).

Opérations sur la méthode (onAccepted, publish_message)


Dans la méthode (onAccepted, publish_message) :

On exécute le méthode (writeData, msgHandler, QrtiDDShandler) si la propriété (text, publish_message, TextField) n'est pas (Vide).
Puis on vide le contenu du composant (TextField, id, publish_message).

Opérations sur le composant (Button, id, publish_messageBtn)


Dans le composant (Button, id, publish_messageBtn) :

On connecte le signal (onClicked) à la méthode (onClicked, publish_messageBtn).

Opérations sur la méthode (onClicked, publish_messageBtn)


Dans la méthode (onClicked, publish_messageBtn):

On exécute le méthode (writeData) du module (msgHandler, QrtiDDShandler) si la propriété (text, publish_message, TextField) n'est pas (Vide).
Puis on vide le contenu du composant (TextField, id, publish_message).

Opérations sur le composant (QrtiDDShandler, id, msgHandler)


Dans le composant (QrtiDDShandler, id, msgHandler) :

On connecte le signal (onNewRcvdDataAvailable) à la méthode (onNewRcvdDataAvailable, msgHandler).

Opérations sur la méthode (onNewRcvdDataAvailable, msgHandler)


Dans la méthode (onNewRcvdDataAvailable, msgHandler):

On exécute le méthode (append) du module (rcvMsg, TextArea).

Opérations sur le composant (Item, id, settingsTab)


Dans le composant (Item, id, settingsTab) :

On crée le composant (ColumnLayout).
On ajoute le composant (TextField, id, myName).
On ajoute le composant (Button, id, setName).
On ajoute le composant (Item, Layout.fillHeight, true).
On ajoute le composant (MessageDialog, id, messageDialog).

Opérations sur le composant (TextField, id, myName)


Dans le composant (TextField, id, myName) :

On connecte le signal (onAccepted) à la méthode (onAccepted, myName).

Opérations sur la méthode (onAccepted, myName)


Dans la méthode (onAccepted, myName):

On met à jour la propriété (myName, root) si la propriété (text, myName, TextField) n'est pas (Vide).
Puis on exécute la méthode (show, messageDialog, MessageDialog).

Opérations sur la méthode (show, messageDialog, MessageDialog)


Dans la méthode (show, messageDialog, MessageDialog):

On met à jour la propriété (text, messageDialog, MessageDialog) avec l'argument (caption).
On exécute la méthode (open, messageDialog, MessageDialog).

Opérations sur le composant (Button, id, publish_messageBtn)


Dans le composant (Button, id, publish_messageBtn) :

On connecte le signal (onClicked) à la méthode (onClicked, publish_messageBtn).

Opérations sur la méthode (onClicked, publish_messageBtn)


Dans la méthode (onClicked, publish_messageBtn):

On exécute le méthode (writeData) du module (msgHandler, QrtiDDShandler) si la propriété (text, publish_message, TextField) n'est pas (Vide).
Puis on vide le contenu du composant (TextField, id, publish_message).