QT+ESP8266+STM32项目构建三部曲三--QT从环境配置到源程序的解析
一、阿里云环境配置
大家在编写QT连接阿里云的程序之前,先按照下面这篇文章让消息可以在阿里云上顺利流转
QT+ESP8266+STM32项目构建三部曲二--阿里云云端处理之云产品流转-CSDN博客文章浏览阅读485次,点赞7次,收藏4次。创建两个设备:一个用于stm32端连接并动态上传数据,一个用于上位机端订阅获取数据添加功能,也就是物模型的的标签,这里根据自己在设计过程中需要的标签,自由设计我这里定义了两个不同数据类型的功能标签自定义一个Topic主题,用来后面进行消息转运点击消息转发中的云产品流转:将两个设备间的消息进行流转,实现下位机上传的数据可以通过云端发送的上位机创建数据源后,在数据源内,创建一个Topic,设备选择用于与下位机相连的创建数据目的数据目的中的这个数字后面编写解析器的时候会用到。https://blog.csdn.net/weixin_54210362/article/details/142445868?spm=1001.2014.3001.5502
二、MQTT外部库的引入
1、MQTT库下载路径
github地址:https://github.com/qt/qtmqtt https://github.com/qt/qtmqtt选择和自己使用的QT版本相匹配的库下载,我使用的是5.14.2版本
将MQTT库文件构建一下,构建的环境要使用Cmake,Cmake可能有的人有,有的人没有,没有的大家,可以在平台上搜索一下配置过程,我这里就不过多描述了。
构建完成后,在自己新建的工程中新建lib文件夹和include文件夹,
①从构建生成的bulid文件下的lib文件夹中找到以下两个文件复制到新建工程下的lib中
②从自己下载下来的那个MQTT库中qtmqtt-5.14.2\src\mqtt,将这个文件夹下的所有.h头文件复制到自己工程新建的include文件夹下
2、 如何在QT软件中设置
添加库
选择外部库
添加下图中方框中的代码
之后就可以进行MQTT库的使用了 ,下面是使用MQTT库应包含的头文件
三、nlohmann/json解析模块引入
因为阿里云传递的信息是Json格式的,我们么可以利用相关库中的函数进行解析,我这里使用了比较受欢迎的nlohman模块.
这里只要将 json/include at develop · nlohmann/json · GitHub 下的 nlohmann 目录拷贝到新建工程的 include 目录下,并添加路径到 VS 工程中,后面只需要引用一个头文件即可:
.pro文件中
四、 MQTT库常用函数解析
下面这五行代码是用来配置客户端的,并没有直接发送出去
mqtt_client->setHostname(HostName);//mqtt_client->setPort(Port);mqtt_client->setUsername(username);mqtt_client->setPassword(password);mqtt_client->setClientId(ClientId);
在这里开始尝试建立联系
//尝试连接云端mqtt_client->connectToHost();
成员函数state是用来检测连接状态的
QMqttClient::ClientState QMqttClient::state() const
{Q_D(const QMqttClient);return d->m_state;
}
开启订阅的函数
QMqttSubscription *QMqttClient::subscribe(const QMqttTopicFilter &topic, quint8 qos)
{return subscribe(topic, QMqttSubscriptionProperties(), qos);
}
发送消息的成员函数publish
//发送消息到云端 {"params":{"temp":137}} 程序运行后,应该用这种方式发送,云端才可以正确解析
qint32 QMqttClient::publish(const QMqttTopicName &topic, const QMqttPublishProperties &properties,const QByteArray &message, quint8 qos, bool retain)
{Q_D(QMqttClient);if (qos > 2)return -1;if (d->m_state != QMqttClient::Connected)return -1;return d->m_connection.sendControlPublish(topic, message, qos, retain, properties);
}
五、整体工程的源码UI设计:
1、mainwindow.ui
2、mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>#include "QDebug"
#include "QLabel"
#include "QFile"
#include "QtMqtt/qmqttclient.h"
#include "QJsonObject"
#include "QJsonDocument"
#include "QJsonArray"
#include "QMessageBox"
#include <nlohmann/json.hpp>
#include <QTextBrowser>
#include <QDateTime>
#include <QTimer>
#include <QFont>
#include <QPalette>QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic://定义可以公开访问的成员变量和成员函数MainWindow(QWidget *parent = nullptr);~MainWindow();void init_mqtt();void sendTopic(QString data);void ConnectOrDisConnect();void Subcribe();void Publish(QString topic);void AnalyzeJson(const QString& jsonString);void Date();public slots://public slots关键字用于声明类的槽函数(slot functions)。槽函数是与信号(signals)关联的特殊类型的成员函数,可以被信号触发。void receiveMess(QByteArray message,QMqttTopicName name);private:QMqttClient *mqtt_client;Ui::MainWindow *ui;QTextBrowser *ui_textBrowser_recv;QTextEdit *textEdit_weight;QTextEdit *textEdit_ID;QTimer *timer;
};
#endif // MAINWINDOW_H
3、mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"#include <iostream>using json = nlohmann::json;static QString HostName="iot-06z00eu4cdskqb7.mqtt.iothub.aliyuncs.com";
static quint16 Port = 1883;
static QString username = "App-Port&k1pcuujbQwk" ;
static QString password = "4b6f2beb66d93e54b9f79a6796d6281ed656a0ea07130df995ecb253d3bfd47c";
static QString ClientId = "k1pcuujbQwk.App-Port|securemode=2,signmethod=hmacsha256,timestamp=1727516084925|";
static QString m_topic_publish= "/sys/k1pcuujbQwk/App-Port/thing/event/property/post";
static QString m_topic_get= "/k1pcuujbQwk/App-Port/user/MessageShift";//放自己自定义的可订阅可发布TopicMainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);
// this->setLayout(ui->verticalLayout);
// ui->widgetBottom->setLayout(ui->horizontalLayout);mqtt_client=new QMqttClient;ConnectOrDisConnect();// 初始化未初始化的成员变量ui_textBrowser_recv = ui->textBrowser_recv; // 假设你的 UI 中有一个名为 textBrowser_recv 的 QTextBrowser 控件textEdit_weight = ui->textEdit_weight; // 假设你的 UI 中有一个名为 textEdit_weight 的 QTextEdit 控件textEdit_ID = ui->textEdit_ID; // 假设你的 UI 中有一个名为 textEdit_ID 的 QTextEdit 控件Publish(m_topic_publish);// 创建一个 QTimer 并设置间隔为 1000 毫秒(1 秒),有了定时就可以达到时间实时显示的效果了timer = new QTimer(this);connect(timer, &QTimer::timeout, this, &MainWindow::Date);// 启动定时器timer->start(1000);// 初始更新时间Date();}MainWindow::~MainWindow()//删除UI,释放资源
{delete ui;
}
/* 此处函数是连接云端的作用,connect(ui->pushButton_connect,&QPushButton::clicked,this,[=](){ 这里使用了Lamda表达式的方法,构建了
一个与按键联系的发送连接信号的事件*/void MainWindow::ConnectOrDisConnect()
{connect(ui->pushButton_connect,&QPushButton::clicked,this,[=](){ //connect,将按键和连接云服务器,点击连接后向服务器发送相应的信息进行连接if(mqtt_client->state()==QMqttClient::Disconnected) //检测当前连接客户端的状态,确认是否连接着、QMqttClient::Disconnected,成员函数{//下面五个语句的作用是配置MQTT客户端,并没有发送任何消息到云端mqtt_client->setHostname(HostName);//mqtt_client->setPort(Port);mqtt_client->setUsername(username);mqtt_client->setPassword(password);mqtt_client->setClientId(ClientId);//尝试连接云端mqtt_client->connectToHost();if(mqtt_client->state()==QMqttClient::Disconnected)//判断是否连接上了mqtt_client->state()是一个连接状态查询的函数{qDebug()<<mqtt_client->error();}else if(mqtt_client->state()==QMqttClient::Connecting){ui->pushButton_connect->setText("close");ui->label_state->setText("Connect");Subcribe();}}else{mqtt_client->disconnectFromHost();ui->pushButton_connect->setText("link");ui->label_state->setText("DisConnect");}});}void MainWindow::Subcribe()
{if(mqtt_client->state()==QMqttClient::Connecting){qDebug()<<"connect success";mqtt_client->subscribe(m_topic_get);connect(mqtt_client, &QMqttClient::messageReceived,this, &MainWindow::receiveMess); //QT5的风格,更加简洁,更加安全}//void receiveMess(QByteArray message,QMqttTopicName name);此处的receiveMess是定义好的,此处直接将messageReceived函数的两个参数按顺序传给后面函数的两个参数}void MainWindow::Publish(QString topic)//发送消息到云端 {"params":{"temp":137}} 发送消息格式
{connect(ui->pushButton_publish,&QPushButton::clicked,this,[=](){if(ui->lineEdit_publish->text()!=""){// 打印用户输入的内容qDebug() << "User input:" << ui->lineEdit_publish->text();if (mqtt_client->publish(topic, ui->lineEdit_publish->text().toUtf8()) == -1){QMessageBox::critical(this, QLatin1String("Error"), QLatin1String("Could not publish message"));//显示对话框的}}});}void MainWindow::AnalyzeJson(const QString& jsonString)//Json字符解析函数,从接收的字符串中解析出自己需要的变量值
{try {// 将QString转换为std::stringstd::string str = jsonString.toStdString();// 解析JSON字符串auto j = json::parse(str);// 获取temp的值if (j.contains("items") && j["items"].contains("temp"))//此处的temp是自己在阿里云上定义的标识符,下面两个也是同理{int tempValue = j["items"]["temp"]["value"];qDebug() << "Temperature value:" << tempValue;}else{qWarning() << "Temperature data not found in JSON";}// 获取Weight的值if (j.contains("items") && j["items"].contains("Weight")){int weightValue = j["items"]["Weight"]["value"];qDebug() << "Weight value:" << weightValue;// 更新textEdit_weight的内容textEdit_weight->setText(QString::number(weightValue));}else{qWarning() << "Weight data not found in JSON";}// 获取ID的值if (j.contains("items") && j["items"].contains("ID")) {std::string idValue = j["items"]["ID"]["value"];qDebug() << "ID value:" << QString::fromStdString(idValue);// 更新textEdit_id的内容textEdit_ID->setText(QString::fromStdString(idValue));} else {qWarning() << "ID data not found in JSON";}// if(j.contains("items") && j["items"].contains("ID"))
// {
// std::string ID = j["items"]["ID"]["value"];// }}catch (const json::exception& e) {qCritical() << "Error parsing JSON:" << e.what();}}void MainWindow::Date()//显示时间日期的模块
{QFont font("Arial", 10, QFont::Bold);//设置字体ui->lineEdit_Date->setFont(font);// 设置文本颜色QPalette palette;palette.setColor(QPalette::Text, Qt::red); // 设置文本颜色为红色ui->lineEdit_Date->setPalette(palette);// setCentralWidget(ui->lineEdit_Date);//将次控件作为中央部件,设置后,其它部件就会消失QDateTime currentDateTime = QDateTime::currentDateTime();QString currentTime = currentDateTime.toString("yyyy-MM-dd hh:mm:ss");ui->lineEdit_Date->setText(currentTime);}void MainWindow::receiveMess(QByteArray message, QMqttTopicName name)//接收信息码,并传给解析函数
{Q_UNUSED(name);QString msg=QString::fromUtf8(message);;//转码,转为UTF-8的编码格式qDebug()<<msg;//打印接收到的信息ui->textBrowser_recv->append(msg);//打印到显示框里AnalyzeJson(msg);//调用解析函数
}
六、资源下载
我前面的那些配置,可能不是每个人按着做下来都对,配置过程总是问题不断,千奇百怪,大家可以去多看看其他博主的,我也是从很多篇里面配出来的环境,问题有很多,大家看的时候,可以多看看评论区。我自己写文章,也是以笔记为主,我会尽量齐全,但还是也不可避免有什么疏忽,请大家一定见谅。
上面其实就是我的所有代码了,如果大家自己将前面的配置都完成了,就不用下文件了,下了也是多余。这个文件如果你不是和我相同版本的话,就是一个参考学习的作用 。
https://download.csdn.net/download/weixin_54210362/89810091?spm=1001.2014.3001.5501
https://download.csdn.net/download/weixin_54210362/89810091?spm=1001.2014.3001.5501
相关文章:

QT+ESP8266+STM32项目构建三部曲三--QT从环境配置到源程序的解析
一、阿里云环境配置 大家在编写QT连接阿里云的程序之前,先按照下面这篇文章让消息可以在阿里云上顺利流转 QTESP8266STM32项目构建三部曲二--阿里云云端处理之云产品流转-CSDN博客文章浏览阅读485次,点赞7次,收藏4次。创建两个设备ÿ…...
Web APIs 5:Window对象(BOM)+本地存储
Web APIs 5(BOM:Window对象本地存储) 1.BOM(浏览器对象模型)(后面几个对象都为BOM对象) BOM对象包含:navigator、location、document(DOM对象)、history、screenBOM是一个全局对象,即JS中的顶…...

神经网络(四):UNet图像分割网络
文章目录 一、简介二、网络结构2.1编码器部分2.2解码器部分2.3完整代码 三、实战案例 论文链接:点击跳转 一、简介 UNet网络是一种用于图像分割的卷积神经网络,其特点是采用了U型网络结构,因此称为UNet。该网络具有编码器和解码器结构&#…...
Java 编码系列:注解处理器详解与面试题解析
引言 在上一篇文章中,我们详细探讨了 Java 注解的基本概念、自定义注解、元注解等技术。本文将继续深入探讨 Java 注解处理器(Annotation Processor),介绍如何编写注解处理器,并结合大厂的最佳实践和面试题详细解析其…...

C语言 | Leetcode C语言题解之第441题排列硬币
题目: 题解: class Solution { public:int arrangeCoins(int n) {return (int) ((sqrt((long long) 8 * n 1) - 1) / 2);} };...

Linux noVNC远程桌面(xfce)部署
一、安装 VNC 服务器和桌面环境 Notebook实验 常用vnc服务 VNC (Virtual Network Computing) 是一种远程桌面协议,可以让你通过网络访问服务器的图形界面。 TurboVNC:专为图形密集型应用设计,尤其适合 3D 可视化和高分辨率图像的远程传输…...
【网络安全】身份认证
1. 身份认证 1.1 定义 身份认证(Authentication)是确认用户身份的过程,确保只有授权的用户才能访问系统或资源。它通常涉及验证用户提供的凭证,如密码、生物特征或其他识别标志。 1.2 重要性 身份认证是信息安全的第一道防线&…...

LeetCode - #124 二叉树中的最大路径和(Top 100)
文章目录 前言1. 描述2. 示例3. 答案关于我们前言 本题为 LeetCode 前 100 高频题 我们社区陆续会将顾毅(Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 LeetCode 算法到目前我们已经更新到 123 期…...

Java:插入排序
目录 排序的概念 插入排序 直接插入排序 哈希排序 排序的概念 排序:所谓的排序,就是使一串记录,按照某个或某些关键字的大小,递增或递减的排列起来的操作。 稳定性:假定在待排序的记录序列中,存在多个…...

How FAR ARE WE FROM AGI?(ICLR AGI Workshop 2024)概览
关注B站可以观看更多实战教学视频:hallo128的个人空间 How FAR ARE WE FROM AGI?官网 How FAR ARE WE FROM AGI?(ICLR AGI Workshop 2024) 该研讨会将于2024年5月11日在奥地利维也纳以混合模式举行,作为 ICLR 2024年会议的一部…...
leetcode刷题day33|动态规划Part02(62.不同路径、63. 不同路径 II、 343.整数拆分、96.不同的二叉搜索树)
62.不同路径 机器人从(0 , 0) 位置出发,到(m - 1, n - 1)终点。 动规五部曲 1、确定dp数组(dp table)以及下标的含义 dp[i][j] :表示从(0 ,0)出发,到(i, j) 有dp[i][j]条不同的路…...

基于Python大数据的B站热门视频的数据分析及可视化系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏:Java精选实战项目…...
matlab-批处理图像质量变化并形成折线图 (PSNR)
%修改路径就能用,图片分辨率要一致 %clc;clear all;close all;tic;%清理内存 file_pathE:\test\resources\image\;% 批量图像所在的文件夹下 file_save_pathE:\test\resources\SaveImage\;% 要存储的地址 img_path_listdir(strcat(file_path,*.jpg));% 获取批量bm…...
[Doc][Ros2]ros2中Qos(Quality of Service,服务质量)介绍
在 ROS 2 中,QoS(Quality of Service,服务质量)是用于控制节点之间消息传递的可靠性、历史存储和数据持久性等方面的机制。通过 QoS 设置,用户可以更细粒度地控制消息传递的行为,确保在不同网络环境或应用场景中满足特定的通信需求。 几个常用的包: QoSProfile: 含义…...

SpringBoot日志集成-LogBack
Log4J:最早的Java日志框架之一,由Apache基金会发起,提供灵活而强大的日志记录机制JDK自带的日志框架:java.util.logging.Logg,是JDK1.4之后提供的日志API,已淘汰logback: logback一个开源的日志…...

Google BigTable架构详解
文章目录 什么是BigTable?架构图一、整体架构二、数据存储与索引存储模型 三、数据拆分与存储四、元数据管理五、读写流程 其他内容概览负载平衡其他存储和数据库选项 什么是BigTable? Bigtable是Google开发的一个高性能、可扩展的分布式存储系统,用于管理大规模…...

【python】如何切换ipynb的kernel至指定conda环境
需求介绍 打开(若无新建环境) 环境 conda env list conda activate cvml conda install ipykernel python -m ipykernel install --name cvml 以上完成后,打开jupyter 创建一个python文件 在kernel——>change kernel——>python[conda env:cvml] 参考资料…...
Linux【基础指令汇总】
目录 Linux命令的特点 1、文件管理 ls命令 cp命令 mkdir命令 mv命令 pwd命令 2、文档编辑 cat命令 echo命令 rm命令 tail命令 rmdir命令 3、系统管理 rpm命令 find命令 startx命令 uname命令 vmstat命令 4、磁盘管理 df命令 fdisk命令 lsblk命令 hdpar…...
SpringCloud-EurekaClient
创建Module pom.xml <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency> spring:application:name: provider # 应用程序的名称,…...
配置Scrapy项目
配置Scrapy项目是一个涉及多个步骤的过程,在上一篇博客中已经写了安装Scrapy、创建Scrapy项目的步骤。 接下来应该定义Item类、编写爬虫程序以及配置settings.py文件等。以下是一个详细的配置Scrapy项目的步骤: 一、定义Item类 在项目目录下…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...

Golang——9、反射和文件操作
反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...