zoukankan      html  css  js  c++  java
  • Qt5.8.0编译QtMqtt库并使用该库连接有人云的例子

    一 编译QtMqtt库
    Qt5.10才官方支持MQTT,但我用的Qt版本是5.8.0 Mingw_32BIT, 为了在Qt5.8.0上添加MQTT支持,需要自己编译源码

    步骤:

    (1) git clone https://github.com/qt/qtmqtt.git

    (2) 使用Qt5.8.0自带的qtcreator打开qtmqtt的pro文件,然后切换到release模式编译

    (3) 编译结束后会在工程生成的文件下生成如下一些文件

    二 连接有人云
    (1)首先按照有人云官方的教程添加一个透传设备,我添加的是“默认设备”(也可以是NBIOT等支持透传的设备),设备的ID为:00021153000000000001

    (2)然后将这个设备使用有人虚拟串口软件映射为本地的虚拟串口,如下图所示

    (3)创建Qt工程,主要代码如下:

    #-------------------------------------------------
    #
    # Project created by QtCreator 2018-12-27T18:02:41
    #
    #-------------------------------------------------

    QT += core gui

    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

    TARGET = MQTTest
    TEMPLATE = app

    # The following define makes your compiler emit warnings if you use
    # any feature of Qt which as been marked as deprecated (the exact warnings
    # depend on your compiler). Please consult the documentation of the
    # deprecated API in order to know how to port your code away from it.
    DEFINES += QT_DEPRECATED_WARNINGS

    # You can also make your code fail to compile if you use deprecated APIs.
    # In order to do so, uncomment the following line.
    # You can also select to disable deprecated APIs only up to a certain version of Qt.
    #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0

    LIBS += -LE:/EWorkSpace/20190109_mqtt/build-qtmqtt-Qt580_MINGW_32BIT-Release/bin -lQt5Mqtt

    INCLUDEPATH += E:/EWorkSpace/20190109_mqtt/build-qtmqtt-Qt580_MINGW_32BIT-Release/include


    SOURCES += main.cpp
    mainwidget.cpp
    mqttclient.cpp

    HEADERS +=
    mainwidget.h
    mqttclient.h

    FORMS +=
    mainwidget.ui
    #ifndef MQTTCLIENT_H
    #define MQTTCLIENT_H

    #include <QObject>
    #include <QtMqtt/QMqttClient>
    #include <QtMqtt/QMqttSubscription>

    typedef QMqttSubscription::SubscriptionState SubscriptionState;

    class MQTTClient : public QObject
    {
    Q_OBJECT
    public:
    explicit MQTTClient(const QString &userName, const QString &passwordMD5, const QString &deviceId, QObject *parent = nullptr);
    ~MQTTClient();

    bool isOpened();
    void open();
    void close();
    void write(const QByteArray &data);

    private:
    QString m_userName;
    QString m_passwordMD5;
    QString m_deviceId;
    QMqttClient *m_client;
    QByteArray m_buffer;

    private slots:
    void doConnected();
    void doDisconnected();
    void doMessageReceived(const QByteArray &message, const QMqttTopicName &topic);
    void doQMqttSubscriptionStateChanged(SubscriptionState subscriptionState);

    signals:
    void log(const QString &text);

    public slots:
    };

    #endif // MQTTCLIENT_H
    #include "mqttclient.h"
    #include <QDebug>

    #define MQTT_HOSTNAME "clouddata.usr.cn"
    #define MQTT_PORT 1883

    #define MQTT_CLIENT_SUBSCRIBE_PREFIX "$USR/DevTx"
    #define MQTT_CLIENT_PUBLISH_PREFIX "$USR/DevRx"

    MQTTClient::MQTTClient(const QString &userName, const QString &passwordMD5, const QString &deviceId, QObject *parent) : QObject(parent)
    {
    m_client=NULL;
    this->m_userName=userName;
    this->m_passwordMD5=passwordMD5;
    this->m_deviceId=deviceId;
    }

    MQTTClient::~MQTTClient()
    {
    if(m_client!=NULL)
    {
    if(m_client->state()==QMqttClient::Connected)
    {
    m_client->disconnectFromHost();
    }
    delete m_client;
    m_client=NULL;
    }
    }

    bool MQTTClient::isOpened()
    {
    if(m_client==NULL)
    {
    return false;
    }
    else if(m_client->state()==QMqttClient::Connected)
    {
    return true;
    }
    else
    {
    return false;
    }
    }

    void MQTTClient::open()
    {
    if(m_client!=NULL)
    {
    return;
    }
    m_client = new QMqttClient(this);
    m_client->setHostname(MQTT_HOSTNAME);
    m_client->setPort(MQTT_PORT);
    m_client->setUsername(m_userName);
    m_client->setClientId(QString("APP:%1").arg(m_userName));
    m_client->setPassword(m_passwordMD5);
    m_client->setProtocolVersion(QMqttClient::MQTT_3_1_1);

    connect(m_client, SIGNAL(connected()), this, SLOT(doConnected()));
    connect(m_client, SIGNAL(disconnected()), this, SLOT(doDisconnected()));
    connect(m_client, SIGNAL(messageReceived(QByteArray,QMqttTopicName)), this, SLOT(doMessageReceived(QByteArray,QMqttTopicName)));

    m_client->connectToHost();
    emit log("MQTTClient 正在连接...");
    }

    void MQTTClient::close()
    {
    if(m_client!=NULL)
    {
    if(m_client->state()==QMqttClient::Connected)
    {
    m_client->disconnectFromHost();
    }
    delete m_client;
    m_client=NULL;
    }
    }

    void MQTTClient::write(const QByteArray &data)
    {
    if(m_client!=NULL)
    {
    m_client->publish(QString("%1/%2").arg(MQTT_CLIENT_PUBLISH_PREFIX).arg(this->m_deviceId), data);
    emit log(QString("MQTTClient 正发布设备消息,设备ID: %1, 消息:%2").arg(this->m_deviceId).arg(QString::fromLatin1(data)));
    }
    }

    void MQTTClient::doConnected()
    {
    emit log("MQTTClient 已建立连接!");
    emit log(QString("MQTTClient 正订阅设备消息,设备ID: %1").arg(this->m_deviceId));
    QMqttSubscription *subscription=m_client->subscribe(QString("%1/%2").arg(MQTT_CLIENT_SUBSCRIBE_PREFIX).arg(this->m_deviceId));
    connect(subscription, SIGNAL(stateChanged(SubscriptionState)),
    this, SLOT(doQMqttSubscriptionStateChanged(SubscriptionState)));
    }

    void MQTTClient::doDisconnected()
    {
    emit log("MQTTClient 已断开连接!");
    this->close();
    }

    void MQTTClient::doMessageReceived(const QByteArray &message, const QMqttTopicName &topic)
    {
    emit log(QString("MQTTClient 接收到数据: %1").arg(QString::fromLatin1(message)));
    }

    void MQTTClient::doQMqttSubscriptionStateChanged(SubscriptionState subscriptionState)
    {
    if(subscriptionState==QMqttSubscription::Subscribed)
    {
    emit log("订阅设备消息成功!");
    }
    }
    #ifndef MAINWIDGET_H
    #define MAINWIDGET_H

    #include <QWidget>
    #include "mqttclient.h"

    namespace Ui {
    class MainWidget;
    }

    class MainWidget : public QWidget
    {
    Q_OBJECT

    public:
    explicit MainWidget(QWidget *parent = 0);
    ~MainWidget();

    private slots:
    void on_buttonConnect_clicked();

    void on_buttonWrite_clicked();

    void on_buttonClear_clicked();

    void doLog(const QString &text);

    private:
    Ui::MainWidget *ui;

    MQTTClient *m_mqttClient;
    };

    #endif // MAINWIDGET_H
    #include "mainwidget.h"
    #include "ui_mainwidget.h"

    MainWidget::MainWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MainWidget)
    {
    ui->setupUi(this);
    m_mqttClient=NULL;
    }

    MainWidget::~MainWidget()
    {
    delete ui;
    }

    void MainWidget::on_buttonConnect_clicked()
    {
    if(m_mqttClient!=NULL)
    {
    m_mqttClient->close();
    m_mqttClient=NULL;
    }
    m_mqttClient=new MQTTClient(ui->lineUsername->text(), ui->linePasswordMD5->text(), ui->lineDeviceId->text());
    connect(m_mqttClient, SIGNAL(log(QString)), this, SLOT(doLog(QString)));
    m_mqttClient->open();
    }

    void MainWidget::on_buttonWrite_clicked()
    {
    if((m_mqttClient==NULL) || (!m_mqttClient->isOpened()))
    {
    ui->textLog->append("MQTT客户端未打开!");
    return;
    }
    m_mqttClient->write(ui->lineWrite->text().toLatin1());
    }

    void MainWidget::on_buttonClear_clicked()
    {
    ui->textLog->clear();
    }

    void MainWidget::doLog(const QString &text)
    {
    ui->textLog->append(text);
    }
    然后运行测试:

    (------- 完 -------)
    ---------------------
    作者:Keycer
    来源:CSDN
    原文:https://blog.csdn.net/zgrjkflmkyc/article/details/86159661
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    【原】ListView的BeginUpdate()和EndUpdate()的用处
    【原】Telerik radwindow 在IE10下偶尔报 unable to get value of the property 'toLowerCase' 的解决办法
    【原】从头学习设计模式(一)——单例模式
    【原】从头学习设计模式(二)——简单工厂模式
    【原】通过JS打开IE新tab(非Window)的解决方案
    【原】高效GTD云工具 ——高效管理你的时间
    【原】安装Win7和Ubuntu双系统后,Win7耳机无声音的解决办法
    【原】从头学习设计模式(三)——工厂方法模式
    【原】备忘:Oracle 中创建存储过程及调用测试一例
    【转】DBA的性格
  • 原文地址:https://www.cnblogs.com/findumars/p/11010866.html
Copyright © 2011-2022 走看看