Qt开发MQTT(一) 之Qt官方Qt MQTT

9 篇文章 49 订阅

概述

Qt开发MQTT程序有两种方式,一个是Qt官方提供的基于MQTT的封装,一个是第三方(EMQ)开发的用于Qt调用MQTT的接口,二者使用方法大同小异,并且均提供了源码。那么,这里先来介绍第一种,如基于Qt官方提供的封装来使用MQTT。

Qt官方虽然在2017年就已经提供了对MQTT的封装,但是并没有正式加入到Qt的标准库里面,所以需要自己下载源码进行编译。

Qt官方介绍文档地址:https://doc.qt.io/QtMQTT/qtmqtt-index.html

下载

Qt官方在github上提供了源代码,地址:https://github.com/qt/qtmqtt
在这里插入图片描述
这是最新的,基于MQTT 5.0协议的版本。先把源码下载下来。

编译

下载源码后得到如下文件,直接打开工程文件准备编译
在这里插入图片描述
我这里的编译环境是:Qt5.12.3+vs2017

注意,编译这个源码需要安装perl,否则会报错:perl 不是内部或外部命令,也不是可运行的程序。

perl下载地址:https://www.perl.org/get.html
官网下载速度比较慢,我上传到网盘了,可以在这里下载:

链接:https://pan.baidu.com/s/1p5YOo-FU-ZLJUtuZSN0Rjg 提取码:i0dm

安装完Perl后会自动写入环境变量, 这时候再次编译(Release模式)QtMqtt源码,编译完成后得到以下文件:
在这里插入图片描述

bin目录下就是我们要的库文件:
在这里插入图片描述

接下来就可以将mqtt部署到自己的Qt项目中了。

部署到Qt项目

编译出来的Qt Mqtt库,要使用它有两种方式,一种是直接在项目中导入外部库和头文件,还有一种是将其以模块的形式部署到Qt的安装目录,其中第二种的好处就是,只需要做一次操作,以后需要再用Mqtt库就可以直接调用了,不需要每次都导入外部库。这里两种方法都介绍一下,首先来看第一种。

导入外部库

新建一个Qt工程
然后将刚刚编译的源码生成目录下的lib文件夹中以下四个文件拷贝:
在这里插入图片描述在这里插入图片描述

在新建工程目录下创建lib文件夹,将拷贝的文件粘贴进去:
在这里插入图片描述
然后在qtmqtt源码目录下(qtmqtt\src\mqtt)的所有.h头文件拷贝,在新建工程目录下创建include文件夹,将拷贝的文件粘贴进去:
在这里插入图片描述

打开新建工程的pro文件,添加:
在这里插入图片描述
再添加库文件引用:

win32:CONFIG(release, debug|release): LIBS += -L$$PWD/lib/ -lQt5Mqtt
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/lib/ -lQt5Mqttd

添加include文件的引用:

INCLUDEPATH += $$PWD/include
DEPENDPATH += $$PWD/include

ok, 这样就可以调用Qt Mqtt的库文件了,直接可以包含头文件来使用了。#include "QtMqtt/QMqttClient"

为了统一演示,先介绍完第二种方法后再来看demo。

部署到Qt安装目录

再来看第二种方法,如何将QtMqtt的库直接部署到Qt安装目录中,这样只需要部署一次,以后在任何工程中引用都不需要再额外导入库了,相比第一种来说更方便些。

首先,将qtmqtt源码目录下(qtmqtt\src\mqtt)的所有.h头文件拷贝,Qt安装目录下的include文件夹中创建一个mqtt目录,将拷贝的文件粘贴进去:
在这里插入图片描述在这里插入图片描述
然后,将源码编译生成目录下的lib中以下6个文件拷贝
在这里插入图片描述
并粘贴到Qt安装目录下的lib文件夹中去:
在这里插入图片描述

接下来将源码编译生成的两个库文件拷贝到Qt安装目录的bin中:
在这里插入图片描述
在这里插入图片描述

最后再拷贝模块配置文件到Qt安装目录中
在这里插入图片描述
在这里插入图片描述

ok,配置完毕,这种方式配置在新建工程中引用只需要引入模块就可以直接使用了

QT += mqtt

包含头文件

#include <QtMqtt/QtMqtt>

所以推荐使用第二种方式进行配置。

接下来看看Demo。

Demo演示

为了方便演示,我们直接使用Qt Mqtt源码中自带的示例来编译运行。
在这里插入图片描述在这里插入图片描述
这个示例Qt官方有详细介绍的,https://doc.qt.io/QtMQTT/qtmqtt-simpleclient-example.html
将该示例打开,有个地方需要改一下,打开Pro文件
在这里插入图片描述
将以上两行注释掉,要不然会有依赖,无法独立运行。

关键代码:

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QtCore/QDateTime>
#include <QtMqtt/QMqttClient>
#include <QtWidgets/QMessageBox>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    m_client = new QMqttClient(this);
    m_client->setHostname(ui->lineEditHost->text());
    m_client->setPort(ui->spinBoxPort->value());

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

    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');
        ui->editLog->insertPlainText(content);
    });

    connect(m_client, &QMqttClient::pingResponseReceived, this, [this]() {
        const QString content = QDateTime::currentDateTime().toString()
                    + QLatin1String(" PingResponse")
                    + QLatin1Char('\n');
        ui->editLog->insertPlainText(content);
    });

    connect(ui->lineEditHost, &QLineEdit::textChanged, m_client, &QMqttClient::setHostname);
    connect(ui->spinBoxPort, QOverload<int>::of(&QSpinBox::valueChanged), this, &MainWindow::setClientPort);
    updateLogStateChange();
}

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

void MainWindow::on_buttonConnect_clicked()
{
    if (m_client->state() == QMqttClient::Disconnected) {
        ui->lineEditHost->setEnabled(false);
        ui->spinBoxPort->setEnabled(false);
        ui->buttonConnect->setText(tr("Disconnect"));
        m_client->connectToHost();
    } else {
        ui->lineEditHost->setEnabled(true);
        ui->spinBoxPort->setEnabled(true);
        ui->buttonConnect->setText(tr("Connect"));
        m_client->disconnectFromHost();
    }
}

void MainWindow::on_buttonQuit_clicked()
{
    QApplication::quit();
}

void MainWindow::updateLogStateChange()
{
    const QString content = QDateTime::currentDateTime().toString()
                    + QLatin1String(": State Change")
                    + QString::number(m_client->state())
                    + QLatin1Char('\n');
    ui->editLog->insertPlainText(content);
}

void MainWindow::brokerDisconnected()
{
    ui->lineEditHost->setEnabled(true);
    ui->spinBoxPort->setEnabled(true);
    ui->buttonConnect->setText(tr("Connect"));
}

void MainWindow::setClientPort(int p)
{
    m_client->setPort(p);
}

void MainWindow::on_buttonPublish_clicked()
{
    if (m_client->publish(ui->lineEditTopic->text(), ui->lineEditMessage->text().toUtf8()) == -1)
        QMessageBox::critical(this, QLatin1String("Error"), QLatin1String("Could not publish message"));
}

void MainWindow::on_buttonSubscribe_clicked()
{
    auto subscription = m_client->subscribe(ui->lineEditTopic->text());
    if (!subscription) {
        QMessageBox::critical(this, QLatin1String("Error"), QLatin1String("Could not subscribe. Is there a valid connection?"));
        return;
    }
}

我们直接编译运行该示例:
broker.hivemq.com
在这里插入图片描述
在官方文档中介绍,可以直接连接以下两个服务器地址:
在这里插入图片描述

经测试,第一个地址连接不上,所以我们直接输入第二个地址进行测试:broker.hivemq.com
在这里插入图片描述
输入地址,点击连接后就可以连接服务器,并且State变成了2就表示已经连上了。
然后点击订阅按钮,表示要订阅这个主题,在点击发布,就可以收到信息了:
在这里插入图片描述
可以在多台电脑上进行测试,只要订阅了同一个主题,那么一端发送消息,其他端就可以接收到相应的信息。

Qt官方提供了非常详细的文档介绍,大家可以去参考接口的使用,最主要使用的类是QMqttClient

至此,Qt官方提供的MQTT封装模块使用介绍已经全部完了,下一篇将介绍一个第三方基于MQTT封装的使用方式。

演示Demo在这里

  • 93
    点赞
  • 569
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 76
    评论
MQTT是一种轻量级的消息传输协议,适合于低带宽、高延迟和不稳定网络环境下的即时通讯。QT是一种跨平台的应用程序开发框架,支持图形用户界面开发、数据库操作、网络应用等。 为了开发MQTT Demo,需要先安装MQTT客户端库,例如MQTT C++客户端库mosquitto_cpp。然后在QT工程中添加mosquitto_cpp头文件和库文件,设置相关编译器选项,并编写业务逻辑。 MQTT Demo主要包括如下功能: 1. 连接MQTT服务器:包括设置MQTT服务器地址、端口号、用户名和密码等参数,建立MQTT连接。 2. 订阅主题:设计订阅主题,过滤器和QoS等参数,实现接收服务器端发来的消息。 3. 发布消息:设置发布消息的主题、内容和QoS等参数,通过MQTT客户端发送数据到服务器端。 4. 断开连接:在程序结束前,对MQTT连接进行正常关闭。 在开发过程中,需要注意以下几点: 1. 异步消息回调机制:mosquitto_cpp提供了异步消息回调机制,需要在类继承mosqpp::mosquittopp时,重载on_message函数,实现接收MQTT消息。 2. 线程安全问题:MQTT连接需要在独立线程中执行,避免阻塞界面操作。 3. 数据结构设计:使用Qt提供的数据结构,如QByteArray、QString等,方便消息的编解码操作。 MQTT Demo的开发需要较强的C++编程能力和熟练运用Qt开发工具,若要实现更为复杂的功能,还需要深入掌握MQTT协议和mosquitto_cpp库的使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 76
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luoyayun361

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值