Diferència entre revisions de la pàgina «Guia per a desenvolupar l'ex07 dels exercicis de QML»
Salta a la navegació
Salta a la cerca
m (→ex07a_02) |
m |
||
(Hi ha 45 revisions intermèdies del mateix usuari que no es mostren) | |||
Línia 1: | Línia 1: | ||
− | = ex07a_01= | + | = Avís important = |
− | == main.qml == | + | 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''' | ||
+ | // ... | ||
+ | === main.qml === | ||
import QtQuick 2.12 | import QtQuick 2.12 | ||
import QtQuick.Window 2.12 | import QtQuick.Window 2.12 | ||
Línia 13: | 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 56: | Línia 63: | ||
} | } | ||
− | = ex07a_02 = | + | == ex07a_02 == |
− | == EstatMqttForm.ui.qml == | + | === EstatMqttForm.ui.qml === |
+ | // ... | ||
+ | '''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 68: | Línia 78: | ||
enabled: false | enabled: false | ||
} | } | ||
− | == main.qml == | + | // ... |
+ | |||
+ | === main.qml === | ||
title: qsTr("ex07a - v0.2") | title: qsTr("ex07a - v0.2") | ||
EstatMqtt{ | EstatMqtt{ | ||
anchors.centerIn: parent | 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 == | ||
+ | === rerefonsmqtt.h === | ||
+ | #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 === | ||
+ | '''#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 === | ||
+ | #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 === | ||
+ | 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: { | btConnecta.onClicked: { | ||
textInfo.text = (textInfo.text === qsTr("MQTT desconnectat"))?qsTr("MQTT connectat"):qsTr("MQTT desconnectat") | textInfo.text = (textInfo.text === qsTr("MQTT desconnectat"))?qsTr("MQTT connectat"):qsTr("MQTT desconnectat") | ||
Línia 78: | Línia 192: | ||
btConnecta.text = (textInfo.text === qsTr("MQTT desconnectat"))?qsTr("&Connecta"):qsTr("Des&connecta") | btConnecta.text = (textInfo.text === qsTr("MQTT desconnectat"))?qsTr("&Connecta"):qsTr("Des&connecta") | ||
btLedBlanc.enabled = (textInfo.text === qsTr("MQTT desconnectat"))?false:true | 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 == | ||
+ | === 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.onClicked: { | ||
Línia 83: | Línia 255: | ||
} | } | ||
} | } | ||
+ | } | ||
+ | |||
+ | == 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
Contingut
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 } // ..