目录
系列文章目录
文章目录
前言
一、JSON是什么
二、上位机与下位机
1.上位机
2.下位机
三、整体设计思路
四、代码
总结
QT的功能十分强大,制作工程类的上位机非常合适。本文将介绍把复杂格式的JSON文件的内容数据提取出来,形成我们所需要的格式并输出为其他文件(本文以输出txt文件为例)。
JSON(JavaScript Object Notation, JS对象简谱)是一种轻量级的数据交换格式。它基于 ECMAScript(European Computer Manufacturers Association, 欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。要充分理解键值对概念。
具体内容附上百科地址:https://baike.baidu.com/item/JSON/2462549?fr=aladdin
本文所用JSON文件如下,仅供参考
{
"description": "file description",
"groups":
[
{
"id": 0,
"start": 0,
"len": 4,
"reverse": 2,
"datas":
[
{
"name": "balabala",
"start": 0,
"len": 8,
"type": "U8",
"columns": 3,
"rows": 1,
"reverse": 5,
"data": [ 0,1,2 ]
},
{
"name": "bala",
"start": 1,
"len": 4,
"type": "U16",
"columns": 1,
"rows": 1,
"reverse": 3,
"data": [ 256 ]
}
],
"checksum": 65535
}
]
}
上位机指可以直接发送操作指令的计算机或单片机,一般提供用户操作交互界面并向用户展示反馈数据。 上位机包含了前端的设计和后端的开发。
典型设备类型:电脑,手机,平板,面板,触摸屏
下位机指直接与机器相连接的计算机或单片机,一般用于接收和反馈上位机的指令,并且根据指令控制机器执行动作以及从机器传感器读取数据。
典型设备类型:PLC,stm32,51,FPGA,ARM等各类可编程芯片
3.1 上位机需求:直接读取json文件,判断json文件正确性。将读取的json文件进行解析,自下而上的获取键值对和数据。自上而下的调用,每一级只和下一级关联,降低复杂性。从最上级将解析完的所有数据获取到,需要进行数据补齐。(例如本次的要求需要所有数据段之和刚好为2kbyte,补齐内容全部为reverse个的0xFF)
3.2 从json文件来看,json文件包含JSON的(文件名+.json),最上级键为description、groups。groups这级下还包含了6个键,其中datas键包含了len-reverse个数据
3.3 UI界面由treeWiget、tableWidget、textEdit组成(暂未完成ui功能)
data类的设计
class Data
{
public:
Data(void);
~Data();
QString name() const;
void setName(const QString &name);
bool isNameValid();
QString dataType() const;
void setDataType(const QString &dataType);
uint8_t getTypeSize(QString &type);
bool isDataTypeValid();
uint start() const;
void setStart(const uint tart);
bool isStartValid();
uint len() const;
void setLen(const uint len);
bool isLenValid();
uint rows() const;
void setRows(const uint rows);
bool isRowsValid();
uint columns() const;
void setColumns(const uint columns);
bool isColumnsValid();
uint reverse() const;
void setReverse(const uint reverse);
bool isReverseValid();
QList &data();
QList &dataValid();
bool isDataValid();
bool isDataFormatOk(); //判断数据是否全正确
bool isJsonFormatOk(const QJsonObject &json); //判断JSON文件是否符合格式要求
void read(const QJsonObject &json);
void write(QJsonObject &json) const;
QByteArray &getDataArray();
void print(int indentation = 0) const;
private:
QHash> DataTypeMap {
{"U8", {1, 0, UINT8_MAX }},
{"S8", {1, INT8_MIN, INT8_MAX }},
{"U16", {2, 0, UINT16_MAX}},
{"S16", {2, INT16_MIN, INT16_MAX}},
{"U32", {4, 0, UINT32_MAX}},
{"S32", {4, INT32_MIN, INT32_MAX}}
};
QString mName; //数据名
bool mIsNameValid;
uint mStart; //起始地址
bool mIsStartValid;
uint mLen; //赋予数据长度
bool mIsLenValid;
QString mType; //数据类型
bool mIsTypeValid;
uint mRows; //数据行号
bool mIsRowsValid;
uint mColumns; //数据列号,其实是把二维的数据看成一维数据
bool mIsColumnsValid;
uint mReverse; //数据剩余长度
bool mIsReverseValid;
QList mData; //数据个数
QList mDataValid;
QByteArray mArray;
};
//Data类中name的设计
QString Data:: name() const
{
return mName;
}
void Data:: setName(const QString &name)
{
mName = name;
mIsNameValid = isNameValid();
}
//判断name是否正确
bool Data:: isNameValid()
{
static QRegularExpression re(R"(^[\w])");
if(!mName.isEmpty() && !mName.contains(re))
{
mIsNameValid = true;
}
else
{
mIsNameValid = false;
}
return mIsNameValid;
}
同理方法,实现类的其他成员函数。最后将所有判断集合。
//判断数据是否全有效
bool Data:: isDataFormatOk()
{
bool ret = true;
if(isNameValid()
&& isDataTypeValid()
&& isStartValid()
&& isLenValid()
&& isRowsValid()
&& isColumnsValid()
&& isReverseValid()
&& isDataValid())
{
ret = true;
}
else
{
ret = false;
}
return ret;
}
//判断json文件是否符合格式
bool Data:: isJsonFormatOk(const QJsonObject &json)
{
if(json.size() != 8)
{
qWarning() << "data size not equal 8";
return false;
}
if (!json.contains("name") || !json["name"].isString())
{
qWarning() << "no name key, or name invalid";
return false;
}
if (!json.contains("start") || !json["start"].isDouble())
{
qWarning() << "no start key, or start invalid";
return false;
}
if (!json.contains("len") || !json["len"].isDouble())
{
qWarning() << "no len key, or len invalid";
return false;
}
if (!json.contains("type") || !json["type"].isString())
{
qWarning() << "no type key, or type invalid";
return false;
}
if (!json.contains("columns") || !json["columns"].isDouble())
{
qWarning() << "no columns key, or columns invalid";
return false;
}
if (!json.contains("rows") || !json["rows"].isDouble())
{
qWarning() << "no rows key, or rows invalid";
return false;
}
if (!json.contains("reverse") || !json["reverse"].isDouble())
{
qWarning() << "no reverse key, or reverse invalid";
return false;
}
if (!json.contains("data") || !json["data"].isArray())
{
qWarning() << "no data key, or data invalid";
return false;
}
QJsonArray array = json["data"].toArray();
for(int i = 0; i < array.size(); i++)
{
if(!array[i].isDouble())
{
qWarning() << "data [i] = " << i << " invalid";
return false;
}
}
return true;
}
Group是Data的上层,包含了Data类。Group类的设计如下
#include
#include
#include
#include "DataParse.h"
#include "JQChecksum.h"
class Group
{
public:
Group();
~Group();
uint id() const;
void setId(const uint id);
bool isIdValid();
uint start() const;
void setStart(const uint start);
bool isStartValid();
uint len() const;
void setLen(const uint len);
bool isLenValid();
uint reverse() const;
void setReverse(const uint reverse);
bool isReverseValid();
QList &data();
QList &dataValid();
bool isDataValid();
bool isGroupFormatOk();
bool isJsonFormatOk(const QJsonObject &json);
bool read(const QJsonObject &json);
void write(QJsonObject &json) const;
QByteArray &getGroupArray();
void print(int indentation = 0) const;
private:
uint mId;
bool mIsIdValid;
uint mStart;//起始地址
bool mIsStartValid;
uint mLen;//数据位长度
bool mIsLenValid;
uint mReverse;//数据位剩余长度
bool mIsReverseValid;
QList mData;
QList mDataValid;
uint mChecksum;//校验和
};
//Group类中id的设计
uint Group :: id() const
{
return mId;
}
void Group :: setId(const uint id)
{
mId = id;
mIsIdValid = isIdValid();
}
bool Group :: isIdValid()
{
mIsIdValid = true;
return mIsIdValid;
}
//判断组内所有的数据是否正确
bool Group :: isDataValid()
{
bool ret = true;
for(int i = 0; i < mData.size(); i++)
{
if(mDataValid[i] == false)
{
ret = false;
break;
}
}
return ret;
}
//判断组内所有的键值对是否正确
bool Group::isGroupFormatOk()
{
bool ret = true;
if(isIdValid()
&& isStartValid()
&& isLenValid()
&& isReverseValid()
&& isDataValid()
)
ret = true;
else
{
ret = false;
}
return ret;
}
//判断JSON文件内键名以及类型是否正确
bool Group::isJsonFormatOk(const QJsonObject &json)
{
if(json.size() != 6)
{
qWarning() << "group size not equal 6";
return false;
}
if (!json.contains("id") || !json["id"].isDouble())
{
qWarning() << "no id key, or id invalid";
return false;
}
if (!json.contains("start") || !json["start"].isDouble())
{
qWarning() << "no start key, or start invalid";
return false;
}
if (!json.contains("len") || !json["len"].isDouble())
{
qWarning() << "no len key, or len invalid";
return false;
}
if (!json.contains("reverse") || !json["reverse"].isDouble())
{
qWarning() << "no reverseLen key, or reverseLen invalid";
return false;
}
if (!json.contains("checksum") || !json["checksum"].isDouble())
{
qWarning() << "no reverseLen key, or reverseLen invalid";
return false;
}
if (!json.contains("datas") || !json["datas"].isArray())
{
qWarning() << "no datas key, or datas invalid";
return false;
}
QJsonArray array = json["datas"].toArray();
Data data1;
for(int i = 0; i < array.size(); i++)
{
if(!data1.isJsonFormatOk(array[i].toObject()))
{
qWarning() << "datas i = " << i << " invalid";
return false;
}
}
return true;
}
EepFile是Group的上层,包含了Group类。EepFIle类的设计如下:EepFile.h
#include
#include
#include
#include "Group.h"
#include
#include
#include "JQChecksum.h"
class EepFile
{
Q_GADGET;
public:
EepFile(void);
~EepFile();
QString description() const;
void setDescription(const QString &name);
// bool isDescriptionValid();
QList &groups();
QList &groupsValid();
bool isGroupsValid();
bool isContentOK();//检查有效性
bool isJsonFormatOk(const QJsonObject &json);
bool read(const QJsonObject &json);
void write(QJsonObject &json) const;
bool readJsonFile(const QString &file);
void readSrecFile(const QString &file);
void WriteSrecFile(QString FileName);//将S39文件写入文件
void WriteJsonFile(QString FileName);
uint8_t checkSum(QByteArray &line);
bool verifyFourByte();
void print() const;
private:
QString mDescription;
// bool mIsDescriptionValid;
QList mGroups;
QList mGroupsValid;
};
关键函数实现及其调用:EepFile.cpp
#include "EepFile.h"
#include
#include
#include
#include
uint8_t crcTable8bit[256] =
{
0x00U, 0x2fU, 0x5eU, 0x71U, 0xbcU, 0x93U, 0xe2U, 0xcdU, 0x57U, 0x78U, 0x09U, 0x26U, 0xebU, 0xc4U, 0xb5U, 0x9aU, //0
0xaeU, 0x81U, 0xf0U, 0xdfU, 0x12U, 0x3dU, 0x4cU, 0x63U, 0xf9U, 0xd6U, 0xa7U, 0x88U, 0x45U, 0x6aU, 0x1bU, 0x34U, //1
0x73U, 0x5cU, 0x2dU, 0x02U, 0xcfU, 0xe0U, 0x91U, 0xbeU, 0x24U, 0x0bU, 0x7aU, 0x55U, 0x98U, 0xb7U, 0xc6U, 0xe9U, //2
0xddU, 0xf2U, 0x83U, 0xacU, 0x61U, 0x4eU, 0x3fU, 0x10U, 0x8aU, 0xa5U, 0xd4U, 0xfbU, 0x36U, 0x19U, 0x68U, 0x47U, //3
0xe6U, 0xc9U, 0xb8U, 0x97U, 0x5aU, 0x75U, 0x04U, 0x2bU, 0xb1U, 0x9eU, 0xefU, 0xc0U, 0x0dU, 0x22U, 0x53U, 0x7cU, //4
0x48U, 0x67U, 0x16U, 0x39U, 0xf4U, 0xdbU, 0xaaU, 0x85U, 0x1fU, 0x30U, 0x41U, 0x6eU, 0xa3U, 0x8cU, 0xfdU, 0xd2U, //5
0x95U, 0xbaU, 0xcbU, 0xe4U, 0x29U, 0x06U, 0x77U, 0x58U, 0xc2U, 0xedU, 0x9cU, 0xb3U, 0x7eU, 0x51U, 0x20U, 0x0fU, //6
0x3bU, 0x14U, 0x65U, 0x4aU, 0x87U, 0xa8U, 0xd9U, 0xf6U, 0x6cU, 0x43U, 0x32U, 0x1dU, 0xd0U, 0xffU, 0x8eU, 0xa1U, //7
0xe3U, 0xccU, 0xbdU, 0x92U, 0x5fU, 0x70U, 0x01U, 0x2eU, 0xb4U, 0x9bU, 0xeaU, 0xc5U, 0x08U, 0x27U, 0x56U, 0x79U, //8
0x4dU, 0x62U, 0x13U, 0x3cU, 0xf1U, 0xdeU, 0xafU, 0x80U, 0x1aU, 0x35U, 0x44U, 0x6bU, 0xa6U, 0x89U, 0xf8U, 0xd7U, //9
0x90U, 0xbfU, 0xceU, 0xe1U, 0x2cU, 0x03U, 0x72U, 0x5dU, 0xc7U, 0xe8U, 0x99U, 0xb6U, 0x7bU, 0x54U, 0x25U, 0x0aU, //A
0x3eU, 0x11U, 0x60U, 0x4fU, 0x82U, 0xadU, 0xdcU, 0xf3U, 0x69U, 0x46U, 0x37U, 0x18U, 0xd5U, 0xfaU, 0x8bU, 0xa4U, //B
0x05U, 0x2aU, 0x5bU, 0x74U, 0xb9U, 0x96U, 0xe7U, 0xc8U, 0x52U, 0x7dU, 0x0cU, 0x23U, 0xeeU, 0xc1U, 0xb0U, 0x9fU, //C
0xabU, 0x84U, 0xf5U, 0xdaU, 0x17U, 0x38U, 0x49U, 0x66U, 0xfcU, 0xd3U, 0xa2U, 0x8dU, 0x40U, 0x6fU, 0x1eU, 0x31U, //D
0x76U, 0x59U, 0x28U, 0x07U, 0xcaU, 0xe5U, 0x94U, 0xbbU, 0x21U, 0x0eU, 0x7fU, 0x50U, 0x9dU, 0xb2U, 0xc3U, 0xecU, //E
0xd8U, 0xf7U, 0x86U, 0xa9U, 0x64U, 0x4bU, 0x3aU, 0x15U, 0x8fU, 0xa0U, 0xd1U, 0xfeU, 0x33U, 0x1cU, 0x6dU, 0x42U //F
};
EepFile :: EepFile(void)
{
}
EepFile :: ~EepFile()
{
}
QString EepFile:: description() const
{
return mDescription;
}
void EepFile:: setDescription(const QString &name)
{
mDescription = name;
// mIsDescriptionValid = isDescriptionValid();
}
//bool EepFile::isDescriptionValid()
//{
// static QRegularExpression re(R"([\w])");
// if( (!mDescription.isEmpty()) && mDescription.contains(re) )
// {
// mIsDescriptionValid = true;
// }
// else
// {
// qWarning() << "description faile";
// mIsDescriptionValid = false;
// }
// return mIsDescriptionValid;
//}
QList &EepFile::groups()
{
return mGroups;
}
QList &EepFile::groupsValid()
{
return mGroupsValid;
}
bool EepFile::isGroupsValid()
{
bool ret = true;
for(int i = 0; i < mGroups.size(); i++)
{
if(!mGroups[i].isContentOk())
{
ret = false;
mGroupsValid[i] = false;
qWarning() << "file::Group i = "<< i << "valid fail" ;
}
else
{
mGroupsValid[i] = true;
}
}
return ret;
}
bool EepFile::isContentOK()
{
bool ret = true;
if( isGroupsValid() )
{
ret = true;
}
else
{
ret = false;
}
return ret;
}
bool EepFile::isJsonFormatOk(const QJsonObject &json)
{
bool ret = true;
if (!json.contains("description") || !json["description"].isString())
{
qWarning() << "no Description key, or Description invalid";
ret = false;
}
if(!json.contains("groups") || !json["groups"].isArray())
{
qWarning() << "no group key, or groups invalid";
ret = false;
}
QJsonArray array = json["groups"].toArray();
Group group1;
for(int i = 0; i < array.size(); i++)
{
if(!group1.isJsonFormatOk(array[i].toObject()))
{
qWarning() << "group i = " << i << " invalid";
return false;
}
}
return ret;
}
bool EepFile :: read(const QJsonObject &json)
{
//同时满足文件格式和文件内容正确时
mDescription = json["description"].toString();
QJsonArray jsonArray = json["groups"].toArray();
mGroups.clear();
mGroups.reserve(jsonArray.size()); //每增加一个数据,就自动为mGroups分配相应的内存空间
mGroupsValid.clear();
mGroupsValid.reserve(jsonArray.size()); //每增加一个数据,就自动为mGroupsValid分配相应的内存空间
for (int index = 0; index < (jsonArray.size()); ++index)
{
if(jsonArray[index].isObject())
{
QJsonObject jsonObject = jsonArray[index].toObject();
Group group;
if(group.read(jsonObject))
{
mGroups.append(group);
mGroupsValid.append(true);
}
else
{
qWarning() << "index = " << index << " failed";
return false;
}
}
else
{
qWarning() << "jsonArray is not object";
return false;
}
}
return true;
}
void EepFile :: write(QJsonObject &json) const
{
json["description"] = mDescription;
QJsonArray jsonArray;
for (const Group &group : mGroups)
{
QJsonObject jsonObject;
group.write(jsonObject);
jsonArray.append(jsonObject);
}
json["datas"] = jsonArray;
}
//QT加载json文件,确保json文件格式正确jsonfromakok(),read()且其内部都正确
bool EepFile :: readJsonFile(const QString &file)
{
QFile eepFile(file);
if (!eepFile.open(QIODevice::ReadOnly))
{
qWarning("Couldn't open file!");
}
QByteArray saveData = eepFile.readAll();//读取文件
eepFile.close();//关闭文件
QJsonParseError error;
QJsonDocument loadDoc(QJsonDocument::fromJson(saveData, &error));
if(error.error != QJsonParseError::NoError)
{
qWarning() << "load Json file error: " + error.errorString();
return false;
}
if(loadDoc.isEmpty())
{
qWarning() << "load Json empty";
return false;
}
QJsonObject obj = loadDoc.object();//获取QJsonObject.并读取Json串中各类型的值。
if(!isJsonFormatOk(obj))
{
qWarning() << "file json fomat not ok";
return false;
}
if(!read(obj))
{
qWarning() << "read ObjJson faile";
return false;
}
print();
if(!isContentOK())
{
qWarning() << "file:: content not ok";
return false;
}
return true;
}
uint8_t EepFile::checkSum(QByteArray &line)
{
uint8_t checksum = 0;
for(int i = 0; i < 21; i++)
{
checksum = checksum + line[i];
}
checksum= ~checksum;
return (checksum & 0xff);
}
//将数据补齐,拼装。最后输出为txt文件。
void EepFile::WriteSrecFile(QString fullFileName)
{
Group group;
QFile file(fullFileName);
QByteArray array;
if(!verifyFourByte())//判断是否四字节对齐
{
return;
}
//提取data
array.clear();
for(Group & group : mGroups)
{
array.append(group.getGroupArray());
}
uint usedlen = array.size();
if(usedlen > 2048)
{
qWarning() << "whole file out range 2048";
return;
}
for(int i = (2048 - usedlen); i > 0; i--)
{
array.append(0xFF);
}
//qDebug() << array.toHex().toUpper();
//拼装数据
QByteArray lastFile;
QByteArray Head = "S00B00005343552E737265632E";
QByteArray Tail = "S70500000411E5";
lastFile.append(Head.toUpper());
lastFile.append('\n');
uint32_t addr = 0x1F800;
uint8_t checksum = 0;
for(int i = 0; i < 2048; i += 16)
{
lastFile.append("S3");
QByteArray line;
line.append(0x15);
line.append((addr>>24) & 0xFF);
line.append((addr>>16) & 0xFF);
line.append((addr>>8) & 0xFF);
line.append(addr & 0xFF);
line.append(array.sliced(i,16));
checksum = checkSum(line);
line.append(checksum);
lastFile.append(line.toHex().toUpper());
lastFile.append('\n');
addr = addr+16;
}
lastFile.append(Tail.toUpper());
lastFile.append('\n');
//输出文件
if(!file.exists())
{
if(!file.open(QIODevice::ReadWrite | QIODevice::Text)) //文件不存在会自动创建
{
qWarning() <<"文件不存在! 创建失败!";
return;
}
}
else
{
if(!file.open(QIODevice::WriteOnly | QIODevice::Text))//重刷文件,源文件会被覆盖
{
qWarning() <<"文件存在,打开文件失败!";
return;
}
}
QTextStream out(&file);
out << lastFile;//把内容输出到指定文件中
file.close();
}
bool EepFile::verifyFourByte()
{
bool ret = true;
for(int i = 0; i < mGroups.size(); i++)
{
if(mGroups[i].len() % 4 != 0)
{
qWarning() << "group: " << i << " No four byte alignment";
ret = false;
}
}
return ret;
}
void EepFile::print() const
{
qDebug() << "mDescription : " << mDescription ;
for(int i = 0; i < mGroups.size(); i++)
{
qDebug() << "============================Group:" << i;
mGroups[i].print();
}
}
为保证严谨,添加了CRC校验,具体要求具体实现,这里提供8位CRC校验,以供参考。
quint8 JQChecksum::crc8(const quint8 init, const QByteArray &data)
{
uint8_t crcTable0x2F[256] =
{
0x00U, 0x2fU, 0x5eU, 0x71U, 0xbcU, 0x93U, 0xe2U, 0xcdU, 0x57U, 0x78U, 0x09U, 0x26U, 0xebU, 0xc4U, 0xb5U, 0x9aU, //0
0xaeU, 0x81U, 0xf0U, 0xdfU, 0x12U, 0x3dU, 0x4cU, 0x63U, 0xf9U, 0xd6U, 0xa7U, 0x88U, 0x45U, 0x6aU, 0x1bU, 0x34U, //1
0x73U, 0x5cU, 0x2dU, 0x02U, 0xcfU, 0xe0U, 0x91U, 0xbeU, 0x24U, 0x0bU, 0x7aU, 0x55U, 0x98U, 0xb7U, 0xc6U, 0xe9U, //2
0xddU, 0xf2U, 0x83U, 0xacU, 0x61U, 0x4eU, 0x3fU, 0x10U, 0x8aU, 0xa5U, 0xd4U, 0xfbU, 0x36U, 0x19U, 0x68U, 0x47U, //3
0xe6U, 0xc9U, 0xb8U, 0x97U, 0x5aU, 0x75U, 0x04U, 0x2bU, 0xb1U, 0x9eU, 0xefU, 0xc0U, 0x0dU, 0x22U, 0x53U, 0x7cU, //4
0x48U, 0x67U, 0x16U, 0x39U, 0xf4U, 0xdbU, 0xaaU, 0x85U, 0x1fU, 0x30U, 0x41U, 0x6eU, 0xa3U, 0x8cU, 0xfdU, 0xd2U, //5
0x95U, 0xbaU, 0xcbU, 0xe4U, 0x29U, 0x06U, 0x77U, 0x58U, 0xc2U, 0xedU, 0x9cU, 0xb3U, 0x7eU, 0x51U, 0x20U, 0x0fU, //6
0x3bU, 0x14U, 0x65U, 0x4aU, 0x87U, 0xa8U, 0xd9U, 0xf6U, 0x6cU, 0x43U, 0x32U, 0x1dU, 0xd0U, 0xffU, 0x8eU, 0xa1U, //7
0xe3U, 0xccU, 0xbdU, 0x92U, 0x5fU, 0x70U, 0x01U, 0x2eU, 0xb4U, 0x9bU, 0xeaU, 0xc5U, 0x08U, 0x27U, 0x56U, 0x79U, //8
0x4dU, 0x62U, 0x13U, 0x3cU, 0xf1U, 0xdeU, 0xafU, 0x80U, 0x1aU, 0x35U, 0x44U, 0x6bU, 0xa6U, 0x89U, 0xf8U, 0xd7U, //9
0x90U, 0xbfU, 0xceU, 0xe1U, 0x2cU, 0x03U, 0x72U, 0x5dU, 0xc7U, 0xe8U, 0x99U, 0xb6U, 0x7bU, 0x54U, 0x25U, 0x0aU, //A
0x3eU, 0x11U, 0x60U, 0x4fU, 0x82U, 0xadU, 0xdcU, 0xf3U, 0x69U, 0x46U, 0x37U, 0x18U, 0xd5U, 0xfaU, 0x8bU, 0xa4U, //B
0x05U, 0x2aU, 0x5bU, 0x74U, 0xb9U, 0x96U, 0xe7U, 0xc8U, 0x52U, 0x7dU, 0x0cU, 0x23U, 0xeeU, 0xc1U, 0xb0U, 0x9fU, //C
0xabU, 0x84U, 0xf5U, 0xdaU, 0x17U, 0x38U, 0x49U, 0x66U, 0xfcU, 0xd3U, 0xa2U, 0x8dU, 0x40U, 0x6fU, 0x1eU, 0x31U, //D
0x76U, 0x59U, 0x28U, 0x07U, 0xcaU, 0xe5U, 0x94U, 0xbbU, 0x21U, 0x0eU, 0x7fU, 0x50U, 0x9dU, 0xb2U, 0xc3U, 0xecU, //E
0xd8U, 0xf7U, 0x86U, 0xa9U, 0x64U, 0x4bU, 0x3aU, 0x15U, 0x8fU, 0xa0U, 0xd1U, 0xfeU, 0x33U, 0x1cU, 0x6dU, 0x42U //F
};
quint8 buf;
quint8 crc = init;
for ( auto i = 0; i < data.size(); ++i )
{
buf = data.at( i ) ^ crc;
crc ^= crcTable0x2F[ buf ];
}
return crc;
}
槽函数:
void MainWindow::on_actionOpen_triggered()
{
QString fileName = QFileDialog::getOpenFileName(this,
tr("Open EEP Config File"), "./", tr("Json Files (*.json)"));
if(!fileName.isEmpty())
{
mFileName = fileName;
qDebug() << fileName;
}
else
{
qWarning() << "not chose right json file";
}
if(!file.readJsonFile(fileName))
{
qWarning() << "file load fail" ;
}
else
{
qInfo() << "file load success" ;
file.WriteSrecFile("./1.txt");
// refreshTree(file);
}
}
将自己学习及做上位机项目的过程分享出来,因为网上关于QT上位机的全方位讲解的特别少,所以就决定将我的代码和心得分享出来,仅供参考!同时QT释放的exe文件运行后,没有出现提示信息。影响了用户使用。可以通过qWarning的重定向,监测qWarning,将其的内容输出到控件以及(文件中)。