qt实现实时抓取串口数据,并对数据做解密处理

效果:

        1.实时抓取串口数据,并对串口数据做解密,解密后显示在QTextEdit上。

        2.对显示的内容做特殊关键字标记处理,比如对出现的Error关键字标红

                高亮另一个版本

        3.对显示的明文进行查询,类似编辑文件中的Ctrl+F

        4.对串口抓取到的数据存储到本地

实现:

        1.在mainwindow中使用串口类子线程对象,其中mHexEdit是显示hex进制数据的自定义控件

MainWindow::~MainWindow()
{mSerialWork->quitWork();delete  mSerialWork;
}void MainWindow::initConnect()
{mLastCursor = new QTextCursor(mSerialEdit->document());mSerialWork = new SerialWorker;connect(mSerialWork, &SerialWorker::readData, this, [&](const QByteArray &data){mHexEdit->appenData(data);
});connect(mSerialWork,&SerialWorker::sendparserslt, this, [&](const QString& data){mSerialEdit->append(data); //mSerialEdit是普通的QTextEdit控件
});
}//dict是解密用的字典文件, serial是串口的属性,比如波特率、停止位等
void MainWindow::startWork(bool start, const QString &dict, const QVariantMap &serial)
{if(!start){mPortList->setEnabled(true);mSerialWork->startWork(0, "", false);return;}auto port = mPortList->currentItem();if(nullptr== port){QMessageBox::warning(this, tr("Warning"),tr("Please select a serial port"));return;}if(dict.isEmpty())return;QVariantMap data = serial;data["port"] = port->text();dicUartParseFilePath = dict;mSerialWork->setProperty(data);mHexEdit->setData(QByteArray());mSerialEdit->clear();mSerialWork->startWork(mProductType, dicUartParseFilePath);
}void MainWindow::saveHexDataToLocal(const QString& path)
{const auto& data = mHexEdit->data();if(data.isEmpty())return;bool ret = false;QString result = tr("Save serial port data failed!");auto lastPath = ParseWork::Instance().getLogFilePath();if(path.isEmpty())return;QFile file(path);if(file.open(QIODevice::WriteOnly|QIODevice::Truncate)){ret = true;file.write(data);file.close();result = tr("Save serial port data successful!");}statusMessage(ret, result);ParseWork::Instance().setLogFilePath(path);
}void MainWindow::ShowStr(const QString& str)
{mSerialEdit->append(str);auto doc = mSerialEdit->document();QTextCursor highlightCursor(doc);auto keywords = ParseWork::Instance().getKeywords();foreach (auto key, keywords.keys()){auto names = key.split("-");QTextCursor cursor(doc);cursor.beginEditBlock();QTextCharFormat plainFormat(mLastCursor->charFormat());QTextCharFormat colorFormat = plainFormat;colorFormat.setForeground(QColor("#ff8911"));while (!highlightCursor.isNull() && !highlightCursor.atEnd()){highlightCursor = doc->find(names[1], *mLastCursor,QTextDocument::FindWholeWords);if (!highlightCursor.isNull()){highlightCursor.select(QTextCursor::LineUnderCursor);highlightCursor.mergeCharFormat(colorFormat);break;}}cursor.endEditBlock();}*mLastCursor = highlightCursor;
}

        2.关于SerialWorker的具体实现,部分无用代码需自己删减

#ifndef SERIALWORKER_H
#define SERIALWORKER_H#include "parse/parsework.h"
#include "utils/utility.h"
#include <QObject>class QThread;
class QSerialPort;
class SerialWorker : public QObject
{Q_OBJECT
public:explicit SerialWorker(QObject *parent = nullptr);~SerialWorker();void setProperty(const QVariantMap& data);void setPortName(const QString& name);void setBaudrate(qint32 rate);void setDataBit(ushort);void setStopBit(ushort bit);void setParity(ushort parity);void startWork(uint product, const QString& dictPath, bool start=true);void quitWork();signals:void openStatus(bool open);void readData(const QByteArray& data);void sendparserslt(QString parseStr);private slots:void readSerialData();private:QThread* mThread;QSerialPort* mSerialPort;QString mPortName;qint32 mBaudrate;ushort mDataBit;ushort mStopBit;ushort mParity;uint mProductType;QString mDictPath;private:unsigned long long dataHasParsedSize = 0;deque<unsigned char> parsedatalist;unsigned int curFileLen = 0;                                    //base on the current file len to split filestd::ofstream *outputBinFile = NULL;FILE *outputTxtFile = NULL;unsigned long saveFileNum = 1;string subFolderName;unsigned int singleFileSize = 20;public:string CreateSaveFolder();bool CreateTextFile(string subFolderName);bool CreateBinaryFile(string subFolderName);string GetProjectName(ProjectItem project);
};#endif // SERIALWORKER_H

  

#include "serialworker.h"#include <QDebug>
#include <QThread>
#include <QSerialPort>
#include <QVariantMap>
#define GET_ENUM_NAME(value) case value:return (#value);
unsigned int parsedcnt = 0;
SerialWorker::SerialWorker(QObject *parent): QObject(parent)
{mSerialPort = new QSerialPort(this);mThread = new QThread;moveToThread(mThread);connect(mSerialPort, &QSerialPort::readyRead, this, &SerialWorker::readSerialData);mThread->start();
}SerialWorker::~SerialWorker()
{quitWork();delete mThread;delete mSerialPort;
}void SerialWorker::setProperty(const QVariantMap &data)
{if(data.isEmpty())return;mPortName = data["port"].toString();mBaudrate = data["buadrate"].toLongLong();mParity   = data["pority"].toUInt();mDataBit  = data["dataBit"].toUInt();mStopBit  = data["stopBit"].toUInt();
}void SerialWorker::setPortName(const QString &name)
{mPortName = name;
}void SerialWorker::setBaudrate(qint32 rate)
{mBaudrate = rate;
}void SerialWorker::setDataBit(ushort bit)
{mDataBit = bit;
}void SerialWorker::setStopBit(ushort bit)
{mStopBit = bit;
}void SerialWorker::setParity(ushort parity)
{mParity = parity;
}void SerialWorker::startWork(uint product, const QString& dictPath, bool start)
{if(!start){mSerialPort->flush();mSerialPort->close();return;}curFileLen = 0;parsedatalist.clear();subFolderName.clear();dataHasParsedSize = 0;mDictPath = dictPath;mProductType = product;QSerialPort::BaudRate baudrate = (QSerialPort::BaudRate)mBaudrate;mSerialPort->setBaudRate(baudrate,QSerialPort::AllDirections);QSerialPort::DataBits dataBits = (QSerialPort::DataBits)mDataBit;mSerialPort->setDataBits(dataBits);mSerialPort->setFlowControl(QSerialPort::NoFlowControl);QSerialPort::Parity parity = (QSerialPort::Parity)mParity;QSerialPort::StopBits stopBits = (QSerialPort::StopBits)mStopBit;mSerialPort->setPortName(mPortName);mSerialPort->setBaudRate(baudrate,QSerialPort::AllDirections);mSerialPort->setDataBits(dataBits);mSerialPort->setParity(parity);mSerialPort->setStopBits(stopBits);mSerialPort->setFlowControl(QSerialPort::NoFlowControl);if(start && !mSerialPort->isOpen()){mSerialPort->open(QIODevice::ReadWrite);}string folderPath = CreateSaveFolder();CreateTextFile(folderPath);CreateBinaryFile(folderPath);openStatus(mSerialPort->isOpen());
}void SerialWorker::quitWork()
{saveFileNum = 1;                 //reset file numberdataHasParsedSize += parsedatalist.size();for(uint i=0;i<parsedatalist.size();i++){outputBinFile->write((char *)&parsedatalist.at(i),1);}if(outputBinFile){outputBinFile->close();outputBinFile = NULL;}if(outputTxtFile){fclose(outputTxtFile);outputTxtFile = NULL;}parsedatalist.clear();parsedcnt = 0;mSerialPort->close();mThread->quit();mThread->wait();
}void SerialWorker::readSerialData()
{const auto& data = mSerialPort->readAll();for(int i=0;i<data.size();i++){parsedatalist.push_back(data.at(i));}QString parseStr;int value1 = parsedatalist.size();switch (mProductType){case TypeO:ParseWork::Instance().ParseTypeOSerialData(parsedatalist,mDictPath,parseStr, outputTxtFile,outputBinFile);case TypeT:ParseWork::Instance().ParseTypeTSerialData(parsedatalist,mDictPath,parseStr, outputTxtFile,outputBinFile);default:break;}if(parseStr.size()){emit sendparserslt(parseStr);}int value2 = parsedatalist.size();parsedcnt += (value1 - value2);if(parsedcnt >= (saveFileNum * singleFileSize * 1024 * 1024)){saveFileNum++;CreateTextFile(subFolderName);CreateBinaryFile(subFolderName);}emit readData(data);
}string SerialWorker::CreateSaveFolder()
{string stCurrentTime = GetCurrentTimeStamp();std::string comName = mPortName.toStdString();string folderName = "SaveInfo_" + comName + "_" +stCurrentTime;string rootdir = get_current_directory();string path = rootdir + "/" + folderName;bool result = CreateFolder(path);if (result)return path;elsereturn "";
}bool SerialWorker::CreateTextFile(string subFolderName)
{if(outputTxtFile){fclose(outputTxtFile);outputTxtFile = NULL;}string project = GetProjectName((ProjectItem)mProductType);char buf[128] = {0};sprintf(buf, "/%s_RS232Log_%ld.txt", project.c_str(), saveFileNum);string saveFileName;saveFileName = subFolderName + buf;outputTxtFile = fopen(saveFileName.data(), "w+");if(outputTxtFile){qDebug()<<"txt file create successfully";}else{qDebug()<<"txt file create fail";}return true;
}bool SerialWorker::CreateBinaryFile(string subFolderName)
{if(outputBinFile){delete outputBinFile;outputBinFile = NULL;}string project = GetProjectName((ProjectItem)mProductType);char buf[100] = {0};sprintf(buf, "/%s_RS232Log_%ld.bin", project.c_str(), saveFileNum);string saveFileName;saveFileName = subFolderName + buf;outputBinFile = new std::ofstream(saveFileName, std::ios::out | std::ios::binary | std::ios::app);if(outputBinFile){qDebug()<<"raw data file create successfully";}else{qDebug()<<"raw data file create fail";}return true;
}string SerialWorker::GetProjectName(ProjectItem project)
{switch (project){GET_ENUM_NAME(PE500 );GET_ENUM_NAME(SQ_UFS_2_2);default:return "";break;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/804897.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mac环境简化RSA密钥生成命令

文章目录 正常RSA密钥对生成操作命令 openssl genrsa -out rsa_private_key.pem 2048 openssl rsa -pubout -in rsa_private_key.pem -out rsa_public_key.pem通过添加环境变量来简化RSA密钥对生成操作 设置环境变量.zshrc或.bash_profile # 使用zsh终端 vim ~/.zshrc将下面sh…

如何通过代码混淆绕过苹果机审,解决APP被拒问题

目录 iOS代码混淆 功能分析 实现流程 类名修改 方法名修改 生成垃圾代码 替换png等静态资源MD5 info.plist文件添加垃圾字段 功能分析 实现流程 类名修改 方法名修改 生成垃圾代码 替换png等静态资源MD5 info.plist文件添加垃圾字段 混淆前后对比 iOS代码混淆 …

南京航空航天大学-考研科目-513测试技术综合 高分整理内容资料-01-单片机原理及应用分层教程-单片机有关常识部分

系列文章目录 高分整理内容资料-01-单片机原理及应用分层教程-单片机有关常识部分 文章目录 系列文章目录前言总结 前言 单片机的基础内容繁杂&#xff0c;有很多同学基础不是很好&#xff0c;对一些细节也没有很好的把握。非常推荐大家去学习一下b站上的哈工大 单片机原理及…

开通抖音小店后下一步要干嘛?这些准备比选品更重要!新手必看!

哈喽~我是电商月月 很多入驻完抖音小店的新手朋友总以为&#xff0c;入驻完抖音小店后&#xff0c;下一步就是去选品 其实并不是&#xff01;选品确实很重要&#xff0c;但前期这几个细节没做好&#xff0c;是会直接影响店铺的整体发展的 废话不多说&#xff0c;直接分享给你…

2024年6月PMP报名已开始!项目经理抓紧啦!

根据《2024年6月1日PMI认证考试报名通知》可知&#xff0c;2024年6月PMP考试安排在6月1日举行&#xff0c;那报名入口什么时候开通呢&#xff1f;2024年6月PMP考试分批报名&#xff0c;从4月10日10:00开启报名&#xff0c;4月18日16:00截止报名。 第一批报名城市&#xff1a;2…

Linux入门攻坚——18、SELinux、Bash脚本编程续

SELinux——Secure Enhanced Linux&#xff08;安全加强的Linux&#xff09;&#xff0c;工作于Linux内核中。 SELinux 主要作用就是最大限度地减小系统中服务进程可访问的资源&#xff08;最小权限原则&#xff09;。采用委任式存取控制&#xff0c;是在进行程序、文件等细节权…

Dockfile相关

一、Dockerfile能干什么? 能在里面自定义应用的各种环境配置,来构建镜像;它是一种实现途径。 1.1Dockerfile文件组成 1.基础镜像信息 FROM 2.维护者信息 LABEL 3.镜像操作指令 ENV ADD COPY RUN 4.启动时执行指令 CMD ENTRYPOINT 1.2Dockerfile多阶段构建 一个镜像的构…

python批量修改替换cad图纸文本,土木狗可以有

civilpy&#xff1a;python进行AutoCAD绘图的两个库&#xff0c;土木狗可以有3 赞同 0 评论文章​编辑 civilpy&#xff1a;python进行AutoCAD绘图批量打印&#xff0c;土木狗可以有2 赞同 2 评论文章​编辑 # 导入所需库 from pyautocad import Autocad, APoint import ma…

LeetCode 94 二叉树的中序遍历

题目描述 二叉树的中序遍历 给定一个二叉树的根节点 root &#xff0c;返回 它的 中序 遍历 。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,3,2]示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[]示例 3&#xff1a; 输入…

hive管理之ctl方式

hive管理之ctl方式 hivehive --service clictl命令行的命令 #清屏 Ctrl L #或者 &#xff01; clear #查看数据仓库中的表 show tabls; #查看数据仓库中的内置函数 show functions;#查看表的结构 desc表名 #查看hdfs上的文件 dfs -ls 目录 #执行操作系统的命令 &#xff01;命令…

WinAppDriver 自动化测试winform程序

WinAppDriver 自动化测试winform程序 前言 WinAppDriver是Windows系统上的一个应用程序驱动工具&#xff0c;开源免费。与Selenium工具类似&#xff0c;都是用来实现产品UI自动化测试的一个工具。 WinAppDriver运行时对系统是有要求的&#xff0c;只能运行在Windows10或Wind…

2024/4/6—力扣—简化路径

代码实现&#xff1a; // 分割/得到名字 char **split(const char *s, int *returnSize) {int n strlen(s);char **ans (char **)malloc(sizeof(char *) * n);int l 0, r 0, len 0;while (r < n) {while (r < n && s[r] /) {r;}l r;while (r < n &…

Python | 海表面温度(SST) | 长期趋势和异常分析

趋势和异常分析&#xff08;Trend and anomaly)在大气和海洋学研究中被广泛用于探测长期变化。 趋势分析&#xff08;Trend Analysis&#xff09;&#xff1a; 趋势分析是一种用于检测数据随时间的变化趋势的方法。在海洋学和大气学中&#xff0c;常见的趋势分析包括海表面温…

WeTrade众汇账户类型有哪几种?FX110网

WeTrade众汇是一个在线交易平台&#xff0c;允许用户买卖各种金融工具&#xff0c;包括交易外汇、金属、能源、指数、股票和加密货币。 WeTrade众汇不仅提供多种交易市场&#xff0c;还提供多种有竞争力的工具和服务。那么&#xff0c;WeTrade众汇账户类型有哪几种&#xff1f;…

CF938Div3(A-F)

A: 买n个酸奶&#xff0c;一次一瓶a元,一次买两瓶可以优惠价b元,也可以a元,问恰好买n瓶需要多少钱. void solve() {int n, a, b;cin >> n >> a >> b;int ans min(a * n, n / 2 * b n % 2 * a);cout << ans << endl; } B: 给你一个数组,问能…

AWVS/Acunetix Premium V24.3.2403高级版漏洞扫描器

前言 Acunetix Premium 是一种 Web 应用程序安全解决方案&#xff0c;用于管理多个网站、Web 应用程序和 API 的安全。集成功能允许您自动化 DevOps 和问题管理基础架构。 Acunetix Premium&#xff1a;全面的 Web 应用程序安全解决方案 Web 应用程序对于企业和组织与客户、…

Vue 大文件切片上传实现指南包会,含【并发上传切片,断点续传,服务器合并切片,计算文件MD5,上传进度显示,秒传】等功能

Vue 大文件切片上传实现指南 背景 在Web开发中&#xff0c;文件上传是一个常见的功能需求&#xff0c;尤其是当涉及到大文件上传时&#xff0c;为了提高上传的稳定性和效率&#xff0c;文件切片上传技术便显得尤为重要。通过将大文件切分成多个小块&#xff08;切片&#xff0…

【Python 基础知识课程】Python的第一个程序

Python 简介 Python 是一种功能强大且用途广泛的编程语言&#xff0c;广泛用于数据科学、Web 开发、自动化等高需求领域。 幸运的是&#xff0c;对于初学者来说&#xff0c;它也是一种很好的学习语言&#xff0c;因为Python代码更容易阅读和编写。它的简单性使其成为初学者的完…

【Qt】:窗口

窗口 一.概述二.菜单栏1.一个简单的菜单2.添加快捷键3.嵌套子菜单4.添加下划线5.添加图标 三.工具栏1.创建一个简单的工具栏2.设置工具栏的停靠位置 四.状态栏五.浮动窗口 一.概述 Qt窗口是通过QMainWindow类来实现的。 QMainWindow是一个为用户提供主窗口程序的类&#xff0c…

hive metatool 使用说明

metatool 使用说明 usage: metatool-dryRun Perform a dry run ofupdateLocation changes.When runwith the dryRun optionupdateLocation changes aredisplayed but not persisted.dryRun is valid only with theupdateLocation option.-ex…