Diferència entre revisions de la pàgina «Guia per a desenvolupar l'ex07 dels exercicis de QML»

De binefa.com
Salta a la navegació Salta a la cerca
m
 
(Hi ha 37 revisions intermèdies del mateix usuari que no es mostren)
Línia 1: Línia 1:
= ex07a_01=
+
= Avís important =
== ex07a_01.pro ==
+
Hom espera que feu aquest exerici 7 de [[Exercicis de QML]] fent servir '''propietats''', tal i com s'ha ensenyat als [[Vídeos QML]]. Aquesta '''solució''' que us faig arribar és '''fent servir senyals''', però vosaltres '''heu d'implementar la solució fent servir ''propietats'''''.
 +
 
 +
= ex07a =
 +
== ex07a_01==
 +
=== ex07a_01.pro ===
 
  QT += quick '''mqtt'''
 
  QT += quick '''mqtt'''
 
  // ...
 
  // ...
== main.qml ==
+
=== main.qml ===
 
  import QtQuick 2.12
 
  import QtQuick 2.12
 
  import QtQuick.Window 2.12  
 
  import QtQuick.Window 2.12  
Línia 16: Línia 20:
 
     }
 
     }
 
  }
 
  }
== EstatMqtt.qml ==
+
=== EstatMqtt.qml ===
 
  import QtQuick 2.4
 
  import QtQuick 2.4
 
   
 
   
 
  EstatMqttForm {
 
  EstatMqttForm {
 
  }
 
  }
== EstatMqttForm.ui.qml ==
+
=== EstatMqttForm.ui.qml ===
 
  import QtQuick 2.4
 
  import QtQuick 2.4
 
  import QtQuick.Controls 2.15
 
  import QtQuick.Controls 2.15
Línia 59: Línia 63:
 
  }
 
  }
  
= ex07a_02 =
+
== ex07a_02 ==
== EstatMqttForm.ui.qml ==
+
=== EstatMqttForm.ui.qml ===
     property alias btLedBlanc: btLedBlanc
+
     // ...
+
    '''property alias btLedBlanc: btLedBlanc'''
 +
    // ...
 
     Button {
 
     Button {
         id: btLedBlanc
+
         id: '''btLedBlanc'''
 
         x: 169
 
         x: 169
 
         text: qsTr("Encén led blanc")
 
         text: qsTr("Encén led blanc")
Línia 73: Línia 78:
 
         enabled: false
 
         enabled: false
 
     }
 
     }
 +
    // ...
  
== main.qml ==
+
=== main.qml ===
 
     title: qsTr("ex07a - v0.2")
 
     title: qsTr("ex07a - v0.2")
 
     EstatMqtt{
 
     EstatMqtt{
Línia 90: Línia 96:
 
     }
 
     }
  
= ex07a_03 =
+
== ex07a_03 ==
== rerefonsmqtt.h ==
+
=== rerefonsmqtt.h ===
 
  #ifndef REREFONSMQTT_H
 
  #ifndef REREFONSMQTT_H
 
  #define REREFONSMQTT_H
 
  #define REREFONSMQTT_H
Línia 115: Línia 121:
 
   
 
   
 
  #endif // REREFONSMQTT_H
 
  #endif // REREFONSMQTT_H
== rerefonsmqtt.cpp ==
+
=== rerefonsmqtt.cpp ===
 
  '''#include "rerefonsmqtt.h"'''
 
  '''#include "rerefonsmqtt.h"'''
 
   
 
   
Línia 129: Línia 135:
 
     '''emit senyalEstatConnexioMqtt(m_nEstat++);'''
 
     '''emit senyalEstatConnexioMqtt(m_nEstat++);'''
 
  }
 
  }
== main.cpp ==
+
=== main.cpp ===
 
  #include <QGuiApplication>
 
  #include <QGuiApplication>
 
  #include <QQmlApplicationEngine>
 
  #include <QQmlApplicationEngine>
Línia 156: Línia 162:
 
     return app.exec();
 
     return app.exec();
 
  }
 
  }
== main.qml ==
+
=== main.qml ===
 
  import QtQuick 2.12
 
  import QtQuick 2.12
 
  import QtQuick.Window 2.12
 
  import QtQuick.Window 2.12
Línia 169: Línia 175:
 
   
 
   
 
   ''' RerefonsMqtt'''{ // <--- !!!!
 
   ''' RerefonsMqtt'''{ // <--- !!!!
         id: rfMqtt
+
         id: '''rfMqtt'''
 
   
 
   
         onSenyalEstatConnexioMqtt: {
+
         '''onSenyalEstatConnexioMqtt''': {
 
             console.log(nEstatConnexioMqtt)
 
             console.log(nEstatConnexioMqtt)
 
         }
 
         }
Línia 194: Línia 200:
 
     }
 
     }
 
  }
 
  }
 +
 +
== ex07a_04 ==
 +
=== main.qml ===
 +
ApplicationWindow {
 +
    '''id: aw'''
 +
    width: 640
 +
    height: 480
 +
    visible: true
 +
    title: qsTr("ex07a - v0.4")
 +
 +
    '''function actualitzaFrontal(nEstatConnexioMqtt)'''{
 +
        switch(nEstatConnexioMqtt){
 +
        case 0:
 +
            eMqtt.textInfo.text = qsTr("MQTT desconnectat")
 +
            eMqtt.textInfo.color = "#ee2222"
 +
            eMqtt.btConnecta.text =qsTr("&Connecta")
 +
            eMqtt.btConnecta.enabled = true
 +
            eMqtt.btLedBlanc.enabled = false
 +
            break;
 +
        case 1:
 +
            eMqtt.textInfo.text = qsTr("MQTT connectant")
 +
            eMqtt.textInfo.color = "#2222ee"
 +
            //eMqtt.btConnecta.enabled = false
 +
            eMqtt.btLedBlanc.enabled = false
 +
            break;
 +
        case 2:
 +
            eMqtt.textInfo.text = qsTr("MQTT connectat")
 +
            eMqtt.textInfo.color = "#22ee22"
 +
            eMqtt.btConnecta.text =qsTr("Des&connecta")
 +
            eMqtt.btConnecta.enabled = true
 +
            eMqtt.btLedBlanc.enabled = true
 +
            break;
 +
        }
 +
    }
 +
 +
    RerefonsMqtt{
 +
        id: '''rfMqtt'''
 +
 +
        onSenyalEstatConnexioMqtt: {
 +
            console.log(nEstatConnexioMqtt)
 +
            '''aw.actualitzaFrontal(nEstatConnexioMqtt)'''
 +
        }
 +
    }
 +
 +
    EstatMqtt{
 +
        '''id: eMqtt''' // <--- !!!!
 +
        anchors.centerIn: parent
 +
 +
        btConnecta.onClicked: {
 +
            '''rfMqtt.vBotoConnectaDesconnectaMqtt()''' // <--- !!!!
 +
        }
 +
        btLedBlanc.onClicked: {
 +
            btLedBlanc.text = (btLedBlanc.text === qsTr("Encén led blanc"))?qsTr("Apaga led blanc"):qsTr("Encén led blanc")
 +
        }
 +
    }
 +
}
 +
 +
== ex07a_05 ==
 +
=== credencials.h ===
 +
#ifndef CREDENCIALS_H
 +
#define CREDENCIALS_H
 +
 +
'''#define BROKER_NAME "formacio.things.cat"'''
 +
'''#define BROKER_PORT 1883'''
 +
'''#define BROKER_USER "ecat"'''
 +
'''#define BROKER_PASSWORD "clotClot"'''
 +
 +
#endif // CREDENCIALS_H
 +
 +
=== rerefonsmqtt.h ===
 +
#include <QMqttClient>
 +
'''#include "credencials.h"'''
 +
// ...
 +
private:
 +
    int m_nEstat;
 +
    '''QMqttClient *m_client;'''
 +
 +
'''private slots:'''
 +
    '''void updateLogStateChange();'''
 +
    '''void brokerDisconnected();'''
 +
// ...
 +
=== rerefonsmqtt.cpp ===
 +
// ...
 +
#include <QtCore/QDateTime>
 +
'''#include <QtMqtt/QMqttClient>'''
 +
#include <QDebug>
 +
 +
RerefonsMqtt::RerefonsMqtt(QObject *parent) : QObject(parent)
 +
{
 +
    m_client = new QMqttClient(this);
 +
    m_client->setHostname(BROKER_NAME);
 +
    m_client->setPort(BROKER_PORT);
 +
 +
    m_nEstat = 1;
 +
 +
    '''connect(m_client, &QMqttClient::stateChanged, this, &RerefonsMqtt::updateLogStateChange);'''
 +
    '''connect(m_client, &QMqttClient::disconnected, this, &RerefonsMqtt::brokerDisconnected);'''
 +
}
 +
 +
void RerefonsMqtt::vBotoConnectaDesconnectaMqtt(){
 +
    '''if (m_client->state() == QMqttClient::Disconnected) {'''
 +
        m_client->setUsername(BROKER_USER);
 +
        m_client->setPassword(BROKER_PASSWORD);
 +
        '''m_client->connectToHost();'''
 +
    } else {
 +
        '''m_client->disconnectFromHost();'''
 +
    }
 +
}
 +
 +
'''void RerefonsMqtt::updateLogStateChange()'''{
 +
    const QString content = QDateTime::currentDateTime().toString()
 +
                    + QLatin1String(": State Change")
 +
                    + QString::number(m_client->state())
 +
                    + QLatin1Char('\n');
 +
    qDebug() << content;
 +
    '''emit senyalEstatConnexioMqtt(m_nEstat = m_client->state());'''
 +
}
 +
 +
'''void RerefonsMqtt::brokerDisconnected()'''{
 +
    qDebug() << "Broker desconnectat!";
 +
}
 +
 +
== ex07a_06 ==
 +
=== temes.h ===
 +
#ifndef TEMES_H
 +
#define TEMES_H
 +
 +
'''#define TOPIC_LED_W "/ledW"'''
 +
 +
#endif // TEMES_H
 +
 +
=== rerefonsmqtt.h ===
 +
// ...
 +
#include "temes.h"
 +
 +
#define MAC_PLACA "AABBCCDDEE01"
 +
// ...
 +
public:
 +
    explicit RerefonsMqtt(QObject *parent = nullptr);
 +
    '''~RerefonsMqtt()''';
 +
// ...
 +
public slots:
 +
    void vBotoConnectaDesconnectaMqtt();
 +
    '''void vPublicaEstatLed(QString szQuinLed,QString szEstat)''';
 +
// ...
 +
=== rerefonsmqtt.cpp ===
 +
RerefonsMqtt::'''~RerefonsMqtt()'''{
 +
    if (m_client->state() == QMqttClient::Connected || m_client->state() == QMqttClient::Connecting) {
 +
        m_client->disconnectFromHost();
 +
    }
 +
}
 +
 +
void RerefonsMqtt::'''vPublicaEstatLed(QString szQuinLed,QString szEstat)'''{
 +
    if(szQuinLed == "w" || szQuinLed == "W" || szQuinLed == "ledW"){
 +
        QString szTopic = QString("/") + MAC_PLACA + TOPIC_LED_W;
 +
        qDebug() << "Tema: " << szTopic << ", Missatge: " << szEstat;
 +
        if ('''m_client->publish(szTopic, szEstat.toUtf8()''') == -1)
 +
            qDebug() << "Error. No es pot publicar el missatge";
 +
    }
 +
}
 +
 +
=== main.qml ===
 +
    EstatMqtt{
 +
        id: eMqtt
 +
        anchors.centerIn: parent
 +
 +
        btConnecta.onClicked: {
 +
            rfMqtt.vBotoConnectaDesconnectaMqtt()
 +
        }
 +
        btLedBlanc.onClicked: {
 +
            btLedBlanc.text = (btLedBlanc.text === qsTr("Encén led blanc"))?qsTr("Apaga led blanc"):qsTr("Encén led blanc")
 +
            '''rfMqtt.vPublicaEstatLed("w",(btLedBlanc.text === qsTr("Encén led blanc"))?"0":"1")'''
 +
        }
 +
    }
 +
= ex07b =
 +
== ex07b_07 ==
 +
=== temes.h ===
 +
#ifndef TEMES_H
 +
#define TEMES_H
 +
 +
#define TOPIC_LED_W "/ledW"
 +
'''#define TOPIC_BT_I35 "/btI35"'''
 +
 +
#endif // TEMES_H
 +
=== rerefonsmqtt.cpp ===
 +
'''RerefonsMqtt::RerefonsMqtt(QObject *parent)''' : QObject(parent)
 +
{
 +
    // ...
 +
    connect(m_client, &QMqttClient::'''messageReceived''', this, '''[this](const QByteArray &message, const QMqttTopicName &topic) {'''
 +
        '''const QString content = QDateTime::currentDateTime().toString()'''
 +
                    '''+ QLatin1String(" Received Topic: ")'''
 +
                    '''+ topic.name()'''
 +
                    '''+ QLatin1String(" Message: ")'''
 +
                    '''+ message'''
 +
                    '''+ QLatin1Char('\n');'''
 +
        '''qDebug() << content;'''
 +
    '''}''');
 +
}
 +
 +
void '''RerefonsMqtt::updateLogStateChange()'''{
 +
    const QString content = QDateTime::currentDateTime().toString()
 +
                    + QLatin1String(": State Change")
 +
                    + QString::number(m_client->state())
 +
                    + QLatin1Char('\n');
 +
    qDebug() << content;
 +
    emit senyalEstatConnexioMqtt(m_nEstat = m_client->state());
 +
 +
    if('''m_nEstat == 2'''){
 +
        '''QString szSubscriptionTopic = QString("/") + MAC_PLACA + TOPIC_BT_I35;'''
 +
        auto subscription = '''m_client->subscribe(szSubscriptionTopic);'''
 +
        if (!subscription) {
 +
            qDebug() << "Error: No m'hi puc subscriure. Hi ha una connexió vàlida?";
 +
            return;
 +
        }else
 +
            qDebug() << "Subscrit a " << szSubscriptionTopic;
 +
    }
 +
}
 +
 +
== ex07b_08 ==
 +
=== rerefonsmqtt.h ===
 +
// ...
 +
private slots:
 +
    void updateLogStateChange();
 +
    void brokerDisconnected();
 +
    '''void vGestionaMissatgeRebut(const QByteArray &message, const QMqttTopicName &topic);'''
 +
// ...
 +
=== rerefonsmqtt.cpp ===
 +
RerefonsMqtt::RerefonsMqtt(QObject *parent) : QObject(parent)
 +
{
 +
    m_client = new QMqttClient(this);
 +
    m_client->setHostname(BROKER_NAME);
 +
    m_client->setPort(BROKER_PORT);
 +
 +
    m_nEstat = 1;
 +
 +
    connect(m_client, &QMqttClient::stateChanged, this, &RerefonsMqtt::updateLogStateChange);
 +
    connect(m_client, &QMqttClient::disconnected, this, &RerefonsMqtt::brokerDisconnected);
 +
    connect(m_client, &QMqttClient::messageReceived, this, '''&RerefonsMqtt::vGestionaMissatgeRebut''');
 +
}
 +
 +
void RerefonsMqtt::'''vGestionaMissatgeRebut(const QByteArray &message, const QMqttTopicName &topic)'''{
 +
    const QString content = QDateTime::currentDateTime().toString()
 +
                + QLatin1String(" Received Topic: ")
 +
                + topic.name()
 +
                + QLatin1String(" Message: ")
 +
                + message
 +
                + QLatin1Char('\n');
 +
    qDebug() << content;
 +
    // Amb més d'un tema subscrit caldria filtrar per tema ( topic.name() )
 +
    '''if(message == "I35 pressed"){'''
 +
        '''qDebug() << "Botó I35 premut";'''
 +
  ''' }'''
 +
    if(message == "I35 released"){
 +
        qDebug() << "Botó I35 no premut";
 +
    }
 +
}
 +
 +
== ex07b_09 ==
 +
=== rerefonsmqtt.h ===
 +
signals:
 +
    void senyalEstatConnexioMqtt(int nEstatConnexioMqtt);
 +
    '''void senyalBotoI35(QString qszTextBotoI35);'''
 +
=== rerefonsmqtt.cpp ===
 +
void RerefonsMqtt::vGestionaMissatgeRebut(const QByteArray &message, const QMqttTopicName &topic){
 +
    // ...
 +
    if(message == "I35 pressed"){
 +
        qDebug() << "Botó I35 premut";
 +
        '''emit senyalBotoI35("Botó I35 premut");'''
 +
    }
 +
    if(message == "I35 released"){
 +
        qDebug() << "Botó I35 no premut";
 +
        '''emit senyalBotoI35("Botó I35 no premut");'''
 +
    }
 +
}
 +
=== main.qml ===
 +
    // ...
 +
    function actualitzaFrontal(nEstatConnexioMqtt){
 +
        switch(nEstatConnexioMqtt){
 +
        case 0:
 +
            // ...
 +
            '''eMqtt.textBotoI35.visible = false'''
 +
            break;
 +
        case 1:
 +
            // ...
 +
        case 2:
 +
            // ...
 +
            '''eMqtt.textBotoI35.visible = true'''
 +
            break;
 +
        }
 +
    }
 +
    // ...
 +
 +
    RerefonsMqtt{
 +
        id: rfMqtt
 +
 +
        onSenyalEstatConnexioMqtt: {
 +
            console.log(nEstatConnexioMqtt)
 +
            aw.actualitzaFrontal(nEstatConnexioMqtt)
 +
        }
 +
        '''onSenyalBotoI35''': {
 +
            console.log(qszTextBotoI35)
 +
            '''eMqtt.textBotoI35.text = qszTextBotoI35'''
 +
        }
 +
    }
 +
 +
=== EstatMqttForm.ui.qml ===
 +
// ..
 +
property alias textBotoI35: textBotoI35
 +
// ..
 +
    Text {
 +
        id: '''textBotoI35'''
 +
        x: 188
 +
        text: qsTr("Botó I35 no premut")
 +
        '''anchors.top: btLedBlanc.bottom'''
 +
        font.pixelSize: 15
 +
        horizontalAlignment: Text.AlignHCenter
 +
        font.bold: true
 +
        minimumPixelSize: 24
 +
        anchors.topMargin: 25
 +
        anchors.horizontalCenter: parent.horizontalCenter
 +
    }
 +
// ..

Revisió de 16:12, 8 feb 2021

Avís important[modifica]

Hom espera que feu aquest exerici 7 de Exercicis de QML fent servir propietats, tal i com s'ha ensenyat als Vídeos QML. Aquesta solució que us faig arribar és fent servir senyals, però vosaltres heu d'implementar la solució fent servir propietats.

ex07a[modifica]

ex07a_01[modifica]

ex07a_01.pro[modifica]

QT += quick mqtt
// ...

main.qml[modifica]

import QtQuick 2.12
import QtQuick.Window 2.12 

Window {
   width: 640
   height: 480
   visible: true
   title: qsTr("ex07a - v0.1")
   EstatMqtt{
       anchors.centerIn: parent
   }
}

EstatMqtt.qml[modifica]

import QtQuick 2.4

EstatMqttForm {
}

EstatMqttForm.ui.qml[modifica]

import QtQuick 2.4
import QtQuick.Controls 2.15

Item {
   id: item1
   width: 400
   height: 400
   property alias btConnecta: btConnecta
   property alias textInfo: textInfo

   Text {
       id: textInfo
       y: 56
       height: 53
       color: "#ee2222"
       text: qsTr("MQTT desconnectat")
       anchors.left: parent.left
       anchors.right: parent.right
       anchors.bottom: btConnecta.top
       font.pixelSize: 35
       horizontalAlignment: Text.AlignHCenter
       anchors.bottomMargin: 25
       anchors.rightMargin: 10
       anchors.leftMargin: 10
       font.bold: true
   }

   Button {
       id: btConnecta
       x: 164
       y: 214
       text: qsTr("&Connecta")
       anchors.verticalCenter: parent.verticalCenter
       anchors.horizontalCenter: parent.horizontalCenter
   }
}

ex07a_02[modifica]

EstatMqttForm.ui.qml[modifica]

   // ...
   property alias btLedBlanc: btLedBlanc
   // ...
   Button {
       id: btLedBlanc
       x: 169
       text: qsTr("Encén led blanc")
       anchors.top: btConnecta.bottom
       anchors.horizontalCenterOffset: 0
       anchors.topMargin: 25
       anchors.horizontalCenter: btConnecta.horizontalCenter
       enabled: false
   }
   // ...

main.qml[modifica]

   title: qsTr("ex07a - v0.2")
   EstatMqtt{
       anchors.centerIn: parent

       btConnecta.onClicked: {
           textInfo.text = (textInfo.text === qsTr("MQTT desconnectat"))?qsTr("MQTT connectat"):qsTr("MQTT desconnectat")
           textInfo.color = (textInfo.text === qsTr("MQTT desconnectat"))?"#ee2222":"#22ee22"
           btConnecta.text = (textInfo.text === qsTr("MQTT desconnectat"))?qsTr("&Connecta"):qsTr("Des&connecta")
           btLedBlanc.enabled = (textInfo.text === qsTr("MQTT desconnectat"))?false:true
       }
       btLedBlanc.onClicked: {
           btLedBlanc.text = (btLedBlanc.text === qsTr("Encén led blanc"))?qsTr("Apaga led blanc"):qsTr("Encén led blanc")
       }
   }

ex07a_03[modifica]

rerefonsmqtt.h[modifica]

#ifndef REREFONSMQTT_H
#define REREFONSMQTT_H

#include <QObject>
#include <QMqttClient>

class RerefonsMqtt : public QObject
{
   Q_OBJECT
public:
   explicit RerefonsMqtt(QObject *parent = nullptr);

signals:
   void senyalEstatConnexioMqtt(int nEstatConnexioMqtt);

public slots:
   void vBotoConnectaDesconnectaMqtt();

private:
   int m_nEstat;
};

#endif // REREFONSMQTT_H

rerefonsmqtt.cpp[modifica]

#include "rerefonsmqtt.h"

RerefonsMqtt::RerefonsMqtt(QObject *parent) : QObject(parent)
{
   m_nEstat = 1;
}

void RerefonsMqtt::vBotoConnectaDesconnectaMqtt(){
   if(m_nEstat > 2)
       m_nEstat = 0;

   emit senyalEstatConnexioMqtt(m_nEstat++);
}

main.cpp[modifica]

#include <QGuiApplication>
#include <QQmlApplicationEngine>

#include "rerefonsmqtt.h"

int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
   QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif

   QGuiApplication app(argc, argv);

   qmlRegisterType<RerefonsMqtt>("desDel.rerefonsMqtt",1,0,"RerefonsMqtt");

   QQmlApplicationEngine engine;
   const QUrl url(QStringLiteral("qrc:/main.qml"));
   QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                    &app, [url](QObject *obj, const QUrl &objUrl) {
       if (!obj && url == objUrl)
           QCoreApplication::exit(-1);
   }, Qt::QueuedConnection);
   engine.load(url);

   return app.exec();
}

main.qml[modifica]

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12 // <---
import desDel.rerefonsMqtt 1.0 // <---

ApplicationWindow { // <--- !!!!
   width: 640
   height: 480
   visible: true
   title: qsTr("ex07a - v0.3")

   RerefonsMqtt{ // <--- !!!!
       id: rfMqtt

       onSenyalEstatConnexioMqtt: {
           console.log(nEstatConnexioMqtt)
       }
   }

   EstatMqtt{
       id: eMqtt // <--- !!!!

       anchors.centerIn: parent

       btConnecta.onClicked: {
           textInfo.text = (textInfo.text === qsTr("MQTT desconnectat"))?qsTr("MQTT connectat"):qsTr("MQTT desconnectat")
           textInfo.color = (textInfo.text === qsTr("MQTT desconnectat"))?"#ee2222":"#22ee22"
           btConnecta.text = (textInfo.text === qsTr("MQTT desconnectat"))?qsTr("&Connecta"):qsTr("Des&connecta")
           btLedBlanc.enabled = (textInfo.text === qsTr("MQTT desconnectat"))?false:true

           rfMqtt.vBotoConnectaDesconnectaMqtt() // <--- !!!!
       }
       btLedBlanc.onClicked: {
           btLedBlanc.text = (btLedBlanc.text === qsTr("Encén led blanc"))?qsTr("Apaga led blanc"):qsTr("Encén led blanc")
       }
   }
}

ex07a_04[modifica]

main.qml[modifica]

ApplicationWindow { 
   id: aw
   width: 640
   height: 480
   visible: true
   title: qsTr("ex07a - v0.4")

   function actualitzaFrontal(nEstatConnexioMqtt){
       switch(nEstatConnexioMqtt){
       case 0:
           eMqtt.textInfo.text = qsTr("MQTT desconnectat")
           eMqtt.textInfo.color = "#ee2222"
           eMqtt.btConnecta.text =qsTr("&Connecta")
           eMqtt.btConnecta.enabled = true
           eMqtt.btLedBlanc.enabled = false
           break;
       case 1:
           eMqtt.textInfo.text = qsTr("MQTT connectant")
           eMqtt.textInfo.color = "#2222ee"
           //eMqtt.btConnecta.enabled = false
           eMqtt.btLedBlanc.enabled = false
           break;
       case 2:
           eMqtt.textInfo.text = qsTr("MQTT connectat")
           eMqtt.textInfo.color = "#22ee22"
           eMqtt.btConnecta.text =qsTr("Des&connecta")
           eMqtt.btConnecta.enabled = true
           eMqtt.btLedBlanc.enabled = true
           break;
       }
   }

   RerefonsMqtt{ 
       id: rfMqtt

       onSenyalEstatConnexioMqtt: {
           console.log(nEstatConnexioMqtt)
           aw.actualitzaFrontal(nEstatConnexioMqtt)
       }
   }

   EstatMqtt{
       id: eMqtt // <--- !!!!
       anchors.centerIn: parent

       btConnecta.onClicked: {
           rfMqtt.vBotoConnectaDesconnectaMqtt() // <--- !!!!
       }
       btLedBlanc.onClicked: {
           btLedBlanc.text = (btLedBlanc.text === qsTr("Encén led blanc"))?qsTr("Apaga led blanc"):qsTr("Encén led blanc")
       }
   }
}

ex07a_05[modifica]

credencials.h[modifica]

#ifndef CREDENCIALS_H
#define CREDENCIALS_H

#define BROKER_NAME "formacio.things.cat"
#define BROKER_PORT 1883
#define BROKER_USER "ecat"
#define BROKER_PASSWORD "clotClot"

#endif // CREDENCIALS_H

rerefonsmqtt.h[modifica]

#include <QMqttClient>
#include "credencials.h"
// ...
private:
   int m_nEstat;
   QMqttClient *m_client;

private slots:
   void updateLogStateChange();
   void brokerDisconnected();
// ...

rerefonsmqtt.cpp[modifica]

// ...
#include <QtCore/QDateTime>
#include <QtMqtt/QMqttClient>
#include <QDebug>

RerefonsMqtt::RerefonsMqtt(QObject *parent) : QObject(parent)
{
   m_client = new QMqttClient(this);
   m_client->setHostname(BROKER_NAME);
   m_client->setPort(BROKER_PORT);

   m_nEstat = 1;

   connect(m_client, &QMqttClient::stateChanged, this, &RerefonsMqtt::updateLogStateChange);
   connect(m_client, &QMqttClient::disconnected, this, &RerefonsMqtt::brokerDisconnected);
}

void RerefonsMqtt::vBotoConnectaDesconnectaMqtt(){
   if (m_client->state() == QMqttClient::Disconnected) {
       m_client->setUsername(BROKER_USER);
       m_client->setPassword(BROKER_PASSWORD);
       m_client->connectToHost();
   } else {
       m_client->disconnectFromHost();
   }
}

void RerefonsMqtt::updateLogStateChange(){
   const QString content = QDateTime::currentDateTime().toString()
                   + QLatin1String(": State Change")
                   + QString::number(m_client->state())
                   + QLatin1Char('\n');
   qDebug() << content;
   emit senyalEstatConnexioMqtt(m_nEstat = m_client->state());
}

void RerefonsMqtt::brokerDisconnected(){
   qDebug() << "Broker desconnectat!";
}

ex07a_06[modifica]

temes.h[modifica]

#ifndef TEMES_H
#define TEMES_H

#define TOPIC_LED_W "/ledW"

#endif // TEMES_H

rerefonsmqtt.h[modifica]

// ...
#include "temes.h"

#define MAC_PLACA "AABBCCDDEE01"
// ...
public:
   explicit RerefonsMqtt(QObject *parent = nullptr);
   ~RerefonsMqtt();
// ...
public slots:
   void vBotoConnectaDesconnectaMqtt();
   void vPublicaEstatLed(QString szQuinLed,QString szEstat);
// ...

rerefonsmqtt.cpp[modifica]

RerefonsMqtt::~RerefonsMqtt(){
   if (m_client->state() == QMqttClient::Connected || m_client->state() == QMqttClient::Connecting) {
       m_client->disconnectFromHost();
   }
}
void RerefonsMqtt::vPublicaEstatLed(QString szQuinLed,QString szEstat){
   if(szQuinLed == "w" || szQuinLed == "W" || szQuinLed == "ledW"){
       QString szTopic = QString("/") + MAC_PLACA + TOPIC_LED_W;
       qDebug() << "Tema: " << szTopic << ", Missatge: " << szEstat;
       if (m_client->publish(szTopic, szEstat.toUtf8()) == -1)
           qDebug() << "Error. No es pot publicar el missatge";
   }
}

main.qml[modifica]

   EstatMqtt{
       id: eMqtt 
       anchors.centerIn: parent

       btConnecta.onClicked: {
           rfMqtt.vBotoConnectaDesconnectaMqtt() 
       }
       btLedBlanc.onClicked: {
           btLedBlanc.text = (btLedBlanc.text === qsTr("Encén led blanc"))?qsTr("Apaga led blanc"):qsTr("Encén led blanc")
           rfMqtt.vPublicaEstatLed("w",(btLedBlanc.text === qsTr("Encén led blanc"))?"0":"1")
       }
   }

ex07b[modifica]

ex07b_07[modifica]

temes.h[modifica]

#ifndef TEMES_H
#define TEMES_H

#define TOPIC_LED_W "/ledW"
#define TOPIC_BT_I35 "/btI35"

#endif // TEMES_H

rerefonsmqtt.cpp[modifica]

RerefonsMqtt::RerefonsMqtt(QObject *parent) : QObject(parent)
{
   // ...
   connect(m_client, &QMqttClient::messageReceived, this, [this](const QByteArray &message, const QMqttTopicName &topic) {
       const QString content = QDateTime::currentDateTime().toString()
                   + QLatin1String(" Received Topic: ")
                   + topic.name()
                   + QLatin1String(" Message: ")
                   + message
                   + QLatin1Char('\n');
       qDebug() << content;
   });
}
void RerefonsMqtt::updateLogStateChange(){
   const QString content = QDateTime::currentDateTime().toString()
                   + QLatin1String(": State Change")
                   + QString::number(m_client->state())
                   + QLatin1Char('\n');
   qDebug() << content;
   emit senyalEstatConnexioMqtt(m_nEstat = m_client->state());

   if(m_nEstat == 2){
       QString szSubscriptionTopic = QString("/") + MAC_PLACA + TOPIC_BT_I35;
       auto subscription = m_client->subscribe(szSubscriptionTopic);
       if (!subscription) {
           qDebug() << "Error: No m'hi puc subscriure. Hi ha una connexió vàlida?";
           return;
       }else
           qDebug() << "Subscrit a " << szSubscriptionTopic;
   }
}

ex07b_08[modifica]

rerefonsmqtt.h[modifica]

// ...
private slots:
   void updateLogStateChange();
   void brokerDisconnected();
   void vGestionaMissatgeRebut(const QByteArray &message, const QMqttTopicName &topic);
// ...

rerefonsmqtt.cpp[modifica]

RerefonsMqtt::RerefonsMqtt(QObject *parent) : QObject(parent)
{
   m_client = new QMqttClient(this);
   m_client->setHostname(BROKER_NAME);
   m_client->setPort(BROKER_PORT);

   m_nEstat = 1;

   connect(m_client, &QMqttClient::stateChanged, this, &RerefonsMqtt::updateLogStateChange);
   connect(m_client, &QMqttClient::disconnected, this, &RerefonsMqtt::brokerDisconnected);
   connect(m_client, &QMqttClient::messageReceived, this, &RerefonsMqtt::vGestionaMissatgeRebut);
}
void RerefonsMqtt::vGestionaMissatgeRebut(const QByteArray &message, const QMqttTopicName &topic){
   const QString content = QDateTime::currentDateTime().toString()
               + QLatin1String(" Received Topic: ")
               + topic.name()
               + QLatin1String(" Message: ")
               + message
               + QLatin1Char('\n');
   qDebug() << content;
   // Amb més d'un tema subscrit caldria filtrar per tema ( topic.name() ) 
   if(message == "I35 pressed"){
       qDebug() << "Botó I35 premut";
   }
   if(message == "I35 released"){
       qDebug() << "Botó I35 no premut";
   }
}

ex07b_09[modifica]

rerefonsmqtt.h[modifica]

signals:
   void senyalEstatConnexioMqtt(int nEstatConnexioMqtt);
   void senyalBotoI35(QString qszTextBotoI35);

rerefonsmqtt.cpp[modifica]

void RerefonsMqtt::vGestionaMissatgeRebut(const QByteArray &message, const QMqttTopicName &topic){
   // ...
   if(message == "I35 pressed"){
       qDebug() << "Botó I35 premut";
       emit senyalBotoI35("Botó I35 premut");
   }
   if(message == "I35 released"){
       qDebug() << "Botó I35 no premut";
       emit senyalBotoI35("Botó I35 no premut");
   }
}

main.qml[modifica]

   // ...
   function actualitzaFrontal(nEstatConnexioMqtt){
       switch(nEstatConnexioMqtt){
       case 0:
           // ...
           eMqtt.textBotoI35.visible = false
           break;
       case 1:
           // ...
       case 2:
           // ...
           eMqtt.textBotoI35.visible = true
           break;
       }
   }
   // ...
   RerefonsMqtt{ 
       id: rfMqtt

       onSenyalEstatConnexioMqtt: {
           console.log(nEstatConnexioMqtt)
           aw.actualitzaFrontal(nEstatConnexioMqtt)
       }
       onSenyalBotoI35: {
           console.log(qszTextBotoI35)
           eMqtt.textBotoI35.text = qszTextBotoI35
       }
   }

EstatMqttForm.ui.qml[modifica]

// ..
property alias textBotoI35: textBotoI35 
// ..
   Text {
       id: textBotoI35
       x: 188
       text: qsTr("Botó I35 no premut")
       anchors.top: btLedBlanc.bottom
       font.pixelSize: 15
       horizontalAlignment: Text.AlignHCenter
       font.bold: true
       minimumPixelSize: 24
       anchors.topMargin: 25
       anchors.horizontalCenter: parent.horizontalCenter
   }
// ..