概述

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在这里

Qt开发MQTT(一) 之Qt官方Qt MQTT相关推荐

  1. Qt开发笔记(一):Qt+FFmpeg开发环境搭建以及工程模板

    原博主博客地址:https://blog.csdn.net/qq21497936 本文章博客地址:https://blog.csdn.net/qq21497936/article/details/90 ...

  2. QT开发(六十四)——QT样式表(二)

    QT开发(六十四)--QT样式表 本文主要翻译自QT官方文档Qt Style Sheets . 五.QT样式表参考 QT样式表支持多种的属性.状态和子控件,使得定制组件的外观成为可能. 1.组件 以下 ...

  3. linux 基于qt开发的音乐,Linux下用QT开发音乐播放器.pdf

    嵌入式课程设计报告 - Linux 在 下开发音乐播放器 李荣贵 141578 一.概述 按课程要求,在Linux环境下开发了一款简易的音乐播放器软件, Mini 名为 " 音乐播放器&qu ...

  4. 适用于树莓派Raspberry Pi的嵌入式QT平台(二) -- 在Windows下用Qt Creator开发编译Raspberry Qt 5应用程序...

    接着上篇 "交叉编译安装Qt Embedded 5.5",我们已经成功在Windows上交叉编译了Raspberry Pi的嵌入式Qt 5.5.那么我们就可以开始开发基于Qt 5的 ...

  5. QT - QT中配置MSVC编译环境 以及 VS中配置QT开发环境

    本文主要记录一下如何在 QT5.14.2 中配置 MSVC2017 构建套件,以及在VS2017中配置QT的开发环境.开发环境为 Win10 +  QT5.14.2 + Visual Studio 2 ...

  6. QT开发学习-第一章-QT简介

    QT简介 一.QT简介 1.QT简介 2.QT优点 二.QT开发工具 1.Qt Creator 2.Qt Designer 3.Qt Linguist 4.Qt Assistant 5.Qmake 6 ...

  7. 细数Qt开发的各种坑(欢迎围观)

    1:Qt的版本多到你数都数不清,多到你开始怀疑人生.从4.6开始到5.8,从MSVC编译器到MINGW编译器,从32位到64位,从Windows到Linux到MAC.MSVC版本还必须安装对应的VS2 ...

  8. 使用Qt开发Github中的开源项目

    游戏2D地图编辑器: 著名的TileMap编辑器,做2D游戏开发的一定不会陌生. Go 语言的IDE: Go语言的集成开发环境. Clementine Music Player: 功能很完善且跨平台支 ...

  9. 基于QT开发的多媒体播放器

    基于QT开发的多媒体播放器 描述: 使用QT软件设计一个多媒体播放器,实现视频及音乐的播放,暂停,快进,快退,音量的调整. 歌词的实时显示和视频全屏播放等基本功能. 功能: 1.音乐系统:提供播放.暂 ...

  10. Matlab+Qt开发笔记(一):matlab搭建Qt开发matlib环境以及Demo测试

    若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/120979753 长期持续带来更多技术分享,定制咨询QQ ...

最新文章

  1. apache工作模式
  2. matlab_simulink笔记01——模块属性的设置以及模块参数的设置
  3. php中json_decode返回数组或对象的实例
  4. java基础基础总结----- Date
  5. python能做什么工作-python语言能做什么工作
  6. shell 计算代码运行时间
  7. Python中函数介绍及其使用
  8. caffe源码解析by薛云峰
  9. Ubuntu CURL下载报错:curl: (77) error setting certificate verify locations:
  10. springboot基于微信小程序的高校学生疫情在校封闭管理系统的设计与实现毕业设计源码240904
  11. centos怎么把计算机调到桌面,CentOS下命令行和桌面模式的切换方法
  12. 微信授权登录,authorize不执行;uniapp 获取用户信息权限失败;无法通过wx.getUserInfo与<button open-type=“getUserInfo“/>获取用户个人信息
  13. TCP/IP网络编程——IO复用
  14. 韩顺平c语言视频笔记,韩顺平视频笔记
  15. 曼哈特软件助力葡萄酒分销商14 Degrees实现业务增长
  16. 洪流之源-FLY LRC歌词
  17. Jenkins官方社区携手灵雀云成功举办Jenkins Meetup
  18. python数据分析实例—— 上海餐饮店数据
  19. Stacks of Flapjacks UVA 薄饼排序问题
  20. 初识马尔科夫模型(Markov Model)

热门文章

  1. 荣耀平板对比测评 用过才知道原来这么香
  2. 计算机学院职权清单,课程清单_计算机科学与技术学院(1).xls
  3. 自学Java随时放弃(十一 循环结构语句③)
  4. 电话诈骗之思考|安全是什么?
  5. 青少年编程 电子学会python编程等级考试一级真题解析(选择题)2021-03
  6. ipython console_Python 安装IPython以及qtconsole
  7. Linux实验5 Samba 服务配置实验实验报告(部分英文)
  8. 我只要一背单词就犯困,你呢?
  9. 吴军:未来被颠覆的六大传统产业
  10. 免费PPT网站,这三个就够了