当前位置: 首页 > news >正文

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 icon-default.png?t=O83Ahttps://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.5501icon-default.png?t=O83Ahttps://download.csdn.net/download/weixin_54210362/89810091?spm=1001.2014.3001.5501

相关文章:

QT+ESP8266+STM32项目构建三部曲三--QT从环境配置到源程序的解析

一、阿里云环境配置 大家在编写QT连接阿里云的程序之前&#xff0c;先按照下面这篇文章让消息可以在阿里云上顺利流转 QTESP8266STM32项目构建三部曲二--阿里云云端处理之云产品流转-CSDN博客文章浏览阅读485次&#xff0c;点赞7次&#xff0c;收藏4次。创建两个设备&#xff…...

Web APIs 5:Window对象(BOM)+本地存储

Web APIs 5&#xff08;BOM&#xff1a;Window对象本地存储&#xff09; 1.BOM(浏览器对象模型)&#xff08;后面几个对象都为BOM对象&#xff09; BOM对象包含&#xff1a;navigator、location、document(DOM对象)、history、screenBOM是一个全局对象&#xff0c;即JS中的顶…...

神经网络(四):UNet图像分割网络

文章目录 一、简介二、网络结构2.1编码器部分2.2解码器部分2.3完整代码 三、实战案例 论文链接&#xff1a;点击跳转 一、简介 UNet网络是一种用于图像分割的卷积神经网络&#xff0c;其特点是采用了U型网络结构&#xff0c;因此称为UNet。该网络具有编码器和解码器结构&#…...

Java 编码系列:注解处理器详解与面试题解析

引言 在上一篇文章中&#xff0c;我们详细探讨了 Java 注解的基本概念、自定义注解、元注解等技术。本文将继续深入探讨 Java 注解处理器&#xff08;Annotation Processor&#xff09;&#xff0c;介绍如何编写注解处理器&#xff0c;并结合大厂的最佳实践和面试题详细解析其…...

C语言 | Leetcode C语言题解之第441题排列硬币

题目&#xff1a; 题解&#xff1a; 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) 是一种远程桌面协议&#xff0c;可以让你通过网络访问服务器的图形界面。 TurboVNC&#xff1a;专为图形密集型应用设计&#xff0c;尤其适合 3D 可视化和高分辨率图像的远程传输…...

【网络安全】身份认证

1. 身份认证 1.1 定义 身份认证&#xff08;Authentication&#xff09;是确认用户身份的过程&#xff0c;确保只有授权的用户才能访问系统或资源。它通常涉及验证用户提供的凭证&#xff0c;如密码、生物特征或其他识别标志。 1.2 重要性 身份认证是信息安全的第一道防线&…...

LeetCode - #124 二叉树中的最大路径和(Top 100)

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

Java:插入排序

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

How FAR ARE WE FROM AGI?(ICLR AGI Workshop 2024)概览

关注B站可以观看更多实战教学视频&#xff1a;hallo128的个人空间 How FAR ARE WE FROM AGI?官网 How FAR ARE WE FROM AGI?&#xff08;ICLR AGI Workshop 2024&#xff09; 该研讨会将于2024年5月11日在奥地利维也纳以混合模式举行&#xff0c;作为 ICLR 2024年会议的一部…...

leetcode刷题day33|动态规划Part02(62.不同路径、63. 不同路径 II、 343.整数拆分、96.不同的二叉搜索树)

62.不同路径 机器人从(0 , 0) 位置出发&#xff0c;到(m - 1, n - 1)终点。 动规五部曲 1、确定dp数组&#xff08;dp table&#xff09;以及下标的含义 dp[i][j] &#xff1a;表示从&#xff08;0 &#xff0c;0&#xff09;出发&#xff0c;到(i, j) 有dp[i][j]条不同的路…...

基于Python大数据的B站热门视频的数据分析及可视化系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…...

matlab-批处理图像质量变化并形成折线图 (PSNR)

%修改路径就能用&#xff0c;图片分辨率要一致 %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&#xff1a;最早的Java日志框架之一&#xff0c;由Apache基金会发起&#xff0c;提供灵活而强大的日志记录机制JDK自带的日志框架&#xff1a;java.util.logging.Logg&#xff0c;是JDK1.4之后提供的日志API&#xff0c;已淘汰logback&#xff1a; logback一个开源的日志…...

Google BigTable架构详解

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

【python】如何切换ipynb的kernel至指定conda环境

需求介绍 打开(若无新建环境) 环境 conda env list conda activate cvml conda install ipykernel python -m ipykernel install --name cvml 以上完成后&#xff0c;打开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 # 应用程序的名称&#xff0c;…...

配置Scrapy项目

配置Scrapy项目是一个涉及多个步骤的过程&#xff0c;在上一篇博客中已经写了安装Scrapy、创建Scrapy项目的步骤。 接下来应该定义Item类、编写爬虫程序以及配置settings.py文件等。以下是一个详细的配置Scrapy项目的步骤&#xff1a; 一、定义Item类 在项目目录下…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

Go 语言接口详解

Go 语言接口详解 核心概念 接口定义 在 Go 语言中&#xff0c;接口是一种抽象类型&#xff0c;它定义了一组方法的集合&#xff1a; // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的&#xff1a; // 矩形结构体…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

Java 二维码

Java 二维码 **技术&#xff1a;**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

Python Einops库:深度学习中的张量操作革命

Einops&#xff08;爱因斯坦操作库&#xff09;就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库&#xff0c;用类似自然语言的表达式替代了晦涩的API调用&#xff0c;彻底改变了深度学习工程…...