You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1165 lines
40 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "BaseSetupWidget.h"
#include "ui_BaseSetupWidget.h"
#include "Common.h"
#include "frame/Frame.h"
#include "device/Device.h"
#include "device/DeviceManager.h"
#include "logger/LogManager.h"
#include "SetupService.h"
#include "Utils.h"
#include "TmsKey.h"
#include <QRegExpValidator>
#include <QTimer>
#include <QMessageBox>
#include <QFileDialog>
#include <sstream>
#include <Qtxlsx>
#include <QDebug>
extern double gZoomValue;
extern unsigned char m_currType;
//const unsigned int gFieldCount = 17;
//tagRecordFile gTagRecordFile[gFieldCount] = {
// {"帧类型", FIELD_TYPE_UCHAR, 1},
// {"序号", FIELD_TYPE_USHORT, 2},
// {"出厂编号", FIELD_TYPE_STRING, 8},
// {"日期", FIELD_TYPE_DATETIME, 7},
// {"设备名称", FIELD_TYPE_STRING, 16},
// {"设备编号", FIELD_TYPE_STRING, 8},
// {"操作人员", FIELD_TYPE_STRING, 16},
// {"目标扭矩", FIELD_TYPE_UINT, 4},
// {"实际扭矩", FIELD_TYPE_UINT, 4},
// {"螺栓规格等级编号", FIELD_TYPE_USHORT, 2},
// {"目标角度", FIELD_TYPE_USHORT, 2},
// {"实际角度", FIELD_TYPE_USHORT, 2},
// {"档位", FIELD_TYPE_UCHAR, 1},
// {"对应扭矩", FIELD_TYPE_UINT, 4},
// {"选定模式", FIELD_TYPE_UCHAR, 1},
// {"运行时间", FIELD_TYPE_USHORT, 2},
// {"拧紧结果", FIELD_TYPE_UCHAR, 1}
//};
const unsigned int gFieldCount = 19;
const unsigned char m_spannerType = 4;
tagRecordFile gTagRecordFile[gFieldCount] = {
{"帧类型", FIELD_TYPE_UCHAR, 1},
{"记录序号", FIELD_TYPE_UINT, 4},
{"工具型号", FIELD_TYPE_STRING, 10},
{"出厂编号", FIELD_TYPE_STRING, 8},
{"日期", FIELD_TYPE_DATETIME, 7},
{"设备名称", FIELD_TYPE_STRING, 16},
{"设备编号", FIELD_TYPE_STRING, 8},
{"操作人员", FIELD_TYPE_STRING, 16},
{"对应压力", FIELD_TYPE_USHORT, 2},
{"目标扭矩", FIELD_TYPE_UINT, 4},
{"实际扭矩", FIELD_TYPE_UINT, 4},
{"螺栓规格", FIELD_TYPE_STRING, 10},
{"螺栓等级", FIELD_TYPE_STRING, 10},
{"目标角度", FIELD_TYPE_USHORT, 2},
{"实际角度", FIELD_TYPE_USHORT, 2},
{"档位", FIELD_TYPE_UCHAR, 1},
{"选定模式", FIELD_TYPE_UCHAR, 1},
{"工作方式", FIELD_TYPE_UCHAR, 1},
{"拧紧结果", FIELD_TYPE_UCHAR, 1}
};
tagRecordFile gTagRecordFileEng[gFieldCount] = {
{"帧类型", FIELD_TYPE_UCHAR, 1},
{"Number", FIELD_TYPE_UINT, 4},
{"Product Type", FIELD_TYPE_STRING, 10},
{"Serial Number", FIELD_TYPE_STRING, 8},
{"Date", FIELD_TYPE_DATETIME, 7},
{"User Equipment Item", FIELD_TYPE_STRING, 16},
{"User Equipment Number", FIELD_TYPE_STRING, 8},
{"Operator", FIELD_TYPE_STRING, 16},
{"Work Pressure", FIELD_TYPE_USHORT, 2},
{"Target Torque", FIELD_TYPE_UINT, 4},
{"Actual Torque", FIELD_TYPE_UINT, 4},
{"Bolt Size", FIELD_TYPE_STRING, 10},
{"Bolt Strength", FIELD_TYPE_STRING, 10},
{"Target Angle", FIELD_TYPE_USHORT, 2},
{"Actual Angle", FIELD_TYPE_USHORT, 2},
{"Gear", FIELD_TYPE_UCHAR, 1},
{"Select Mode", FIELD_TYPE_UCHAR, 1},
{"Work Pattern", FIELD_TYPE_UCHAR, 1},
{"Fastening Result", FIELD_TYPE_UCHAR, 1}
};
BaseSetupWidget::BaseSetupWidget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::BaseSetupWidget)
//, m_sysStatus(SYS_STATUS_IDLE)
, m_currCmd(FRAME_CMD_START)
, m_bSucc(false)
{
ui->setupUi(this);
init();
// 初始化定时器0用于显示系统时间
initTimer0();
// 初始化文件记录定时器
initRecordTimer();
// // Excel初始化
// m_excelObject = new QAxObject("Excel.Application");
// // 是否可视化excel
// m_excelObject->dynamicCall("SetVisible(bool Visble)", "false");
// // 是否弹出警告窗口
// m_excelObject->setProperty("DisplayAlerts", false);
}
BaseSetupWidget::~BaseSetupWidget()
{
clearTimer0();
// if(m_excelObject != nullptr)
// {
// m_excelObject->dynamicCall("Quit()");
// delete m_excelObject;
// m_excelObject = nullptr;
// }
delete ui;
}
void BaseSetupWidget::init()
{
// 控件大小
int nLabelWidth = 120 * gZoomValue;
int nLabelHeight = gnDefaultLabelHeight * gZoomValue;
ui->labelToolsUnlock->setFixedSize(nLabelWidth, nLabelHeight);
ui->labelToolsSerialNumber->setFixedSize(nLabelWidth, nLabelHeight);
ui->labelTimeSetting->setFixedSize(nLabelWidth, nLabelHeight);
ui->labelUserEquitmentItem->setFixedSize(nLabelWidth, nLabelHeight);
ui->labelUserEquitmentNo->setFixedSize(nLabelWidth, nLabelHeight);
ui->labelOperatorSettings->setFixedSize(nLabelWidth, nLabelHeight);
ui->labelRecordedData->setFixedSize(nLabelWidth, nLabelHeight);
int nLineEditHeight = gnDefaultLineEditHeight * gZoomValue;
ui->lineEditToolsUnlock->setFixedHeight(nLineEditHeight);
ui->lineEditToolsSerialNumber->setFixedHeight(nLineEditHeight);
ui->lineEditTimeSetting->setFixedHeight(nLineEditHeight);
ui->lineEditUserEquitmentItem->setFixedHeight(nLineEditHeight);
ui->lineEditUserEquitmentNo->setFixedHeight(nLineEditHeight);
ui->lineEditOperatorSettings->setFixedHeight(nLineEditHeight);
int nPushButtonWidth = 130 * gZoomValue;
int nPushButtonHeight = gnDefaultPushButtonHeight * gZoomValue;
int nWidgetHeight = nPushButtonHeight;
ui->widget_7->setFixedHeight(nWidgetHeight);
ui->pushButtonGetRecords->setFixedWidth(80 * gZoomValue);
ui->pushButtonGetRecords->setFixedHeight(nPushButtonHeight);
ui->pushButtonToolsUnlock->setFixedSize(nPushButtonWidth, nPushButtonHeight);
ui->pushButtonToolsSerialNumber->setFixedSize(nPushButtonWidth, nPushButtonHeight);
ui->pushButtonTimeSetting->setFixedSize(nPushButtonWidth, nPushButtonHeight);
ui->pushButtonUserEquitmentItem->setFixedSize(nPushButtonWidth, nPushButtonHeight);
ui->pushButtonUserEquitmentNo->setFixedSize(nPushButtonWidth, nPushButtonHeight);
ui->pushButtonOperatorSettings->setFixedSize(nPushButtonWidth, nPushButtonHeight);
ui->pushButtonDeleteRecordedData->setFixedSize(nPushButtonWidth, nPushButtonHeight);
// 进度条不可用,不可见
ui->progressBarGetRecords->setDisabled(true);
ui->progressBarGetRecords->setValue(0);
// 控件字体
QString strStyleSheet = gstrStyleSheet.arg(gnFontSize * gZoomValue);
ui->lineEditToolsUnlock->setStyleSheet(strStyleSheet);
ui->lineEditToolsSerialNumber->setStyleSheet(strStyleSheet);
// 时间不可编辑
ui->lineEditTimeSetting->setEnabled(false);
ui->lineEditTimeSetting->setStyleSheet(strStyleSheet);
ui->lineEditUserEquitmentItem->setStyleSheet(strStyleSheet);
ui->lineEditUserEquitmentNo->setStyleSheet(strStyleSheet);
ui->lineEditOperatorSettings->setStyleSheet(strStyleSheet);
// 定义只能输入数字的正则表达式
QRegExp regx("[0-9]+$");
//QValidator *validator1 = new QRegExpValidator(regx, ui->lineEditUserEquitmentNo);
QValidator *validator = new QRegExpValidator(regx);
// 设置解除锁定的密码最多输入8位数字
ui->lineEditToolsUnlock->setValidator(validator);
ui->lineEditToolsUnlock->setMaxLength(8);
// 设置出厂编号最多输入8位数字
ui->lineEditToolsSerialNumber->setValidator(validator);
ui->lineEditToolsSerialNumber->setMaxLength(8);
// 设置设备名称最多输入长度16中文字算长度1英文字符也是长度1
ui->lineEditUserEquitmentItem->setMaxLength(8);
// 设置设备编号最多输入8位数字
ui->lineEditUserEquitmentNo->setValidator(validator);
ui->lineEditUserEquitmentNo->setMaxLength(8);
// 设置操作人员最多输入长度8中文字算长度1英文字符也是长度1
ui->lineEditUserEquitmentItem->setMaxLength(8);
// 解锁
connect(ui->pushButtonToolsUnlock, SIGNAL(clicked()), this, SLOT(slot_pushButtonToolsUnlock_clicked()));
// 出厂编号
connect(ui->pushButtonToolsSerialNumber, SIGNAL(clicked()), this, SLOT(slot_pushButtonToolsSerialNumber_clicked()));
// 设置时间
connect(ui->pushButtonTimeSetting, SIGNAL(clicked()), this, SLOT(slot_pushButtonTimeSetting_clicked()));
// 设置设备名称
connect(ui->pushButtonUserEquitmentItem, SIGNAL(clicked()), this, SLOT(slot_pushButtonUserEquitmentItem_clicked()));
// 设置设备编号
connect(ui->pushButtonUserEquitmentNo, SIGNAL(clicked()), this, SLOT(slot_pushButtonUserEquitmentNo_clicked()));
// 操作人员编辑
connect(ui->pushButtonOperatorSettings, SIGNAL(clicked()), this, SLOT(slot_pushButtonOperatorSettings_clicked()));
// 获取记录
connect(ui->pushButtonGetRecords, SIGNAL(clicked()), this, SLOT(slot_pushButtonGetRecords_clicked()));
// 清除记录
connect(ui->pushButtonDeleteRecordedData, SIGNAL(clicked()), this, SLOT(slot_pushButtonDeleteRecordedData_clicked()));
}
//
// 初始化定时器
//
void BaseSetupWidget::initTimer0()
{
m_timer0.stop();
m_timer0.setInterval(100);//1ms定时器类似于单片机的中断函数
connect(&m_timer0, SIGNAL(timeout()),this,SLOT(slot_timer0_task()));
//当记满1000时执行Timer0_Task
m_timer0.start();
}
void BaseSetupWidget::clearTimer0()
{
m_timer0.stop();
disconnect(&m_timer0, SIGNAL(timeout()),this,SLOT(slot_timer0_task()));
}
//
// 定时器0的功能在设置时间的lineEdit框中显示当前时间
//
void BaseSetupWidget::slot_timer0_task()
{
QString d = QDate::currentDate().toString("yyyy-MM-dd");
QString t = QTime::currentTime().toString("hh:mm:ss");
ui->lineEditTimeSetting->setText(tr("%1 %2").arg(d).arg(t));
}
//
// 解除锁定
//
void BaseSetupWidget::slot_pushButtonToolsUnlock_clicked()
{
logInfo("请求解锁...");
char c[2] = {0};
c[0] = 0x00; // 0x00 解锁0x01加锁
c[1] = '\0';
std::string s;
s.append(c, 1);
s.append(ui->lineEditToolsUnlock->text().toStdString());
SetupService::GetInstance()->SendData(FRAME_CMD_SET_LOCK_STATUS, s);
}
//
// 设置出厂编号
//
void BaseSetupWidget::slot_pushButtonToolsSerialNumber_clicked()
{
logInfo("请求设置出厂序列号...");
SetupService::GetInstance()->SendData(FRAME_CMD_SET_SERIAL_NUMBER, ui->lineEditToolsSerialNumber->text().toStdString().substr(0, 8));
}
//
// 设置时间
//
void BaseSetupWidget::slot_pushButtonTimeSetting_clicked()
{
logInfo(tr("请求设置日期时间..."));
SetupService::GetInstance()->SendData(FRAME_CMD_SET_TIME);
}
//
// 设置设备名称
//
void BaseSetupWidget::slot_pushButtonUserEquitmentItem_clicked()
{
logInfo(tr("请求设置设备名称..."));
// 设备名称中英文混合一个中文utf8编码为3字节英文字符为1字节混排计算长度
QString s = ui->lineEditUserEquitmentItem->text();
while(s.toStdString().length() > 16)
{
s = s.left(s.length()-1);
}
//SendData(FRAME_CMD_SET_DEVICE_NAME, ui->lineEditUserEquitmentItem->text().toStdString().substr(0, 16));
SetupService::GetInstance()->SendData(FRAME_CMD_SET_DEVICE_NAME, s.toStdString());
}
//
// 设置设备编号
//
void BaseSetupWidget::slot_pushButtonUserEquitmentNo_clicked()
{
logInfo(tr("请求设置设备序列号..."));
SetupService::GetInstance()->SendData(FRAME_CMD_SET_DEVICE_NUMBER, ui->lineEditUserEquitmentNo->text().toStdString().substr(0, 8));
}
//
// 设置操作人
//
void BaseSetupWidget::slot_pushButtonOperatorSettings_clicked()
{
logInfo(tr("请求设置操作人..."));
// 操作人名称可中文可英文一个中文utf8编码为3字节英文字符为1字节混排计算长度
QString s = ui->lineEditOperatorSettings->text();
while(s.toStdString().length() > 16)
{
s = s.left(s.length()-1);
}
SetupService::GetInstance()->SendData(FRAME_CMD_SET_OPERATOR, s.toStdString());
}
void BaseSetupWidget::slot_pushButtonGetRecords_clicked()
{
logInfo("请求获取记录数据...");
m_recordAllCount = 0; // 清空文件总记录数
m_recordCurrCount = 0; // 清空当前收到记录数
m_recordData.clear(); // 清空文件内容列表
m_recordFlag = false; // 尚未开始记录,收到起始帧才算真正的开始
SetupService::GetInstance()->SendData(FRAME_CMD_GET_RECORD, "", 2000);
// saveRecordToFile();
}
//
// 删除记录
//
void BaseSetupWidget::slot_pushButtonDeleteRecordedData_clicked()
{
logInfo(tr("请求删除记录数据..."));
SetupService::GetInstance()->SendData(FRAME_CMD_CLS_RECORD);
}
void BaseSetupWidget::slot_recvData(QString portName, unsigned char cmd, QByteArray recvData)
{
//QMessageBox::warning(this, "Warning!", "BaseSetupWidget::slot_recvData", QMessageBox::Ok, QMessageBox::Ok);
#ifdef _DEBUG
logInfo(tr("PORT:%1 >> Recv Data: CMD=[%2]%3").arg(portName).arg(cmd).arg(QString::fromStdString(getCmdName(cmd))));
#else
logInfo(tr("PORT:%1 >> Recv Data: CMD=%2").arg(portName).arg(QString::fromStdString(getCmdName(cmd))));
#endif
switch(cmd)
{
case FRAME_CMD_SET_TIME : processSetTimeRsp(portName, recvData); break;
case FRAME_CMD_GET_TIME : processGetTimeRsp(portName, recvData); break;
case FRAME_CMD_SET_SERIAL_NUMBER: processSetSerialNumberRsp(portName, recvData); break;
case FRAME_CMD_GET_SERIAL_NUMBER: processGetSerialNumberRsp(portName, recvData); break;
case FRAME_CMD_SET_DEVICE_NAME : processSetDeviceNameRsp(portName, recvData); break;
case FRAME_CMD_GET_DEVICE_NAME : processGetDeviceNameRsp(portName, recvData); break;
case FRAME_CMD_SET_DEVICE_NUMBER: processSetDeviceNumberRsp(portName, recvData); break;
case FRAME_CMD_GET_DEVICE_NUMBER: processGetDeviceNumberRsp(portName, recvData); break;
case FRAME_CMD_GET_RECORD : processGetRecordRsp(portName, recvData); break;
case FRAME_CMD_CLS_RECORD : processClsRecordRsp(portName, recvData); break;
case FRAME_CMD_SET_OPERATOR : processSetOperatorRsp(portName, recvData); break;
case FRAME_CMD_GET_OPERATOR : processGetOperatorRsp(portName, recvData); break;
case FRAME_CMD_SET_LOCK_STATUS : processSetLockStatusRsp(portName, recvData); break;
default:
logInfo(tr("PORT:%1 >> Unsupported CMD Of Base Setup[%2]!").arg(portName).arg(cmd));
break;
}
}
//
// 设置时间响应
//
void BaseSetupWidget::processSetTimeRsp(QString portName, QByteArray data)
{
#ifdef _DEBUG
logDebug(tr("PORT:%1 >> SET TIME SUCCESS[%2]").arg(portName).arg(Utils::strToHexStr(data.toStdString()).c_str()));
#else
logInfo(tr("PORT:%1 >> SET TIME SUCCESS").arg(portName));
#endif
}
//
// 获取时间响应 -- 暂无此功能
//
void BaseSetupWidget::processGetTimeRsp(QString portName, QByteArray data)
{
#ifdef _DEBUG
logDebug(tr("PORT:%1 >> GET TIME SUCCESS[%2]").arg(portName).arg(Utils::strToHexStr(data.toStdString()).c_str()));
#else
logInfo(tr("PORT:%1 >> GET TIME SUCCESS").arg(portName));
#endif
}
//
// 设置出厂序列号响应
//
void BaseSetupWidget::processSetSerialNumberRsp(QString portName, QByteArray data)
{
#ifdef _DEBUG
logDebug(tr("PORT:%1 >> SET SERIAL NUMBER SUCCESS[%2]").arg(portName).arg(Utils::strToHexStr(data.toStdString()).c_str()));
#else
logInfo(tr("PORT:%1 >> SET SERIAL NUMBER SUCCESS").arg(portName));
#endif
}
//
// 获取出厂序列号响应 -- 系统启动时自动请求获取
//
void BaseSetupWidget::processGetSerialNumberRsp(QString portName, QByteArray data)
{
#ifdef _DEBUG
logDebug(tr("PORT:%1 >> GET SERIAL NUMBER SUCCESS![%2][%3]")
.arg(portName)
.arg(Utils::strToHexStr(data.toStdString()).c_str())
.arg(data.toStdString().c_str()));
#else
logInfo(tr("PORT:%1 >> GET SERIAL NUMBER SUCCESS").arg(portName));
#endif
ui->lineEditToolsSerialNumber->setText(data);
}
//
// 设置设备名称响应
//
void BaseSetupWidget::processSetDeviceNameRsp(QString portName, QByteArray data)
{
#ifdef _DEBUG
logDebug(tr("PORT:%1 >> SET DEVICE NAME SUCCESS[%2]").arg(portName).arg(Utils::strToHexStr(data.toStdString()).c_str()));
#else
logInfo(tr("PORT:%1 >> SET DEVICE NAME SUCCESS").arg(portName));
#endif
}
//
// 获取设备名称响应 -- 系统启动时自动请求获取
//
void BaseSetupWidget::processGetDeviceNameRsp(QString portName, QByteArray data)
{
#ifdef _DEBUG
logDebug(tr("PORT:%1 >> GET DEVICE NAME SUCCESS[%2]").arg(portName).arg(Utils::strToHexStr(data.toStdString()).c_str()));
#else
logInfo(tr("PORT:%1 >> GET DEVICE NAME SUCCESS").arg(portName));
#endif
ui->lineEditUserEquitmentItem->setText(data);
}
//
// 设置设备序列号响应
//
void BaseSetupWidget::processSetDeviceNumberRsp(QString portName, QByteArray data)
{
#ifdef _DEBUG
logDebug(tr("PORT:%1 >> SET DEVICE NUMBER SUCCESS[%2]").arg(portName).arg(Utils::strToHexStr(data.toStdString()).c_str()));
#else
logInfo(tr("PORT:%1 >> SET DEVICE NUMBER SUCCESS").arg(portName));
#endif
}
//
// 获取设备序列号响应 -- 系统启动时自动请求获取
//
void BaseSetupWidget::processGetDeviceNumberRsp(QString portName, QByteArray data)
{
#ifdef _DEBUG
logDebug(tr("PORT:%1 >> GET DEVICE NUMBER SUCCESS[%2]").arg(portName).arg(Utils::strToHexStr(data.toStdString()).c_str()));
#else
logInfo(tr("PORT:%1 >> GET DEVICE NUMBER SUCCESS").arg(portName));
#endif
ui->lineEditUserEquitmentNo->setText(data);
}
//
// 设置操作人响应
//
void BaseSetupWidget::processSetOperatorRsp(QString portName, QByteArray data)
{
#ifdef _DEBUG
logDebug(tr("PORT:%1 >> SET OPERATOR SUCCESS[%2]").arg(portName).arg(Utils::strToHexStr(data.toStdString()).c_str()));
#else
logInfo(tr("PORT:%1 >> SET OPERATOR SUCCESS").arg(portName));
#endif
}
//
// 获取操作人响应
//
void BaseSetupWidget::processGetOperatorRsp(QString portName, QByteArray data)
{
#ifdef _DEBUG
logDebug(tr("PORT:%1 >> GET OPERATOR SUCCESS[%2]").arg(portName).arg(Utils::strToHexStr(data.toStdString()).c_str()));
#else
logInfo(tr("PORT:%1 >> GET OPERATOR SUCCESS").arg(portName));
#endif
ui->lineEditOperatorSettings->setText(data);
}
//
// 获取记录响应
//
void BaseSetupWidget::processGetRecordRsp(QString portName, QByteArray data)
{
#ifdef _DEBUG
logDebug(tr("PORT:%1 >> GET RECORD SUCCESS[%2]").arg(portName).arg(Utils::strToHexStr(data.toStdString()).c_str()));
#endif
if(data.length() < 1)
{
logInfo(tr("PORT:%1 >> 返回数据格式错误!").arg(portName));
emit get_record_finish(-1);
return;
}
unsigned char type = data.at(0);
switch(type)
{
case 0x00: // 起始帧
logInfo(tr("PORT:%1 >> 文件记录 - 收到起始帧").arg(portName));
if(!m_recordFlag)
{
if(data.length() < 3)
{
logInfo(tr("PORT:%1 >> 返回数据格式错误0x00!").arg(portName));
emit get_record_finish(-1);
return;
}
m_recordFlag = true;
m_recordAllCount = Utils::charToShort(data.at(1), data.at(2));
// 设置进度条可用可见
ui->progressBarGetRecords->setEnabled(true);
ui->progressBarGetRecords->setVisible(true);
ui->progressBarGetRecords->setValue(0);
startRecordTimer(1000);
}
break;
case 0x01: // 数据帧
logInfo(tr("PORT:%1 >> 文件记录 - 收到数据帧").arg(portName));
if(m_recordFlag)
{
if(data.length() < 81) // 目前数据长度为81
{
logInfo(tr("PORT:%1 >> 返回数据格式错误0x01!").arg(portName));
emit get_record_finish(-1);
return;
}
// 收到数据即停止定时器,然后将数据放入队列,再启动定时器
stopRecordTimer();
// 将数据放入队列
m_recordData.push_back(QString::fromLatin1(data, data.length()));
m_recordCurrCount++;
// 设置进度条的值
ui->progressBarGetRecords->setValue(m_recordCurrCount / m_recordCurrCount);
startRecordTimer(1000);
}
else
{
logInfo(tr("PORT:%1 >> Record Flag is false!").arg(portName));
}
break;
case 0x02: // 结束帧
logInfo(tr("PORT:%1 >> 文件记录 - 收到结束帧").arg(portName));
if(m_recordFlag)
{
m_recordFlag = false;
stopRecordTimer();
ui->progressBarGetRecords->setValue(100);
// 将数据存为文件
saveRecordToFile();
emit get_record_finish(0);
ui->progressBarGetRecords->setDisabled(true);
}
break;
default:
logInfo(tr("PORT:%1 >> Unknown Type[%1]").arg(portName).arg(type));
break;
}
return;
}
//
// 清除记录按钮点击响应
//
void BaseSetupWidget::processClsRecordRsp(QString portName, QByteArray data)
{
#ifdef _DEBUG
logDebug(tr("PORT:%1 >> CLS RECORD SUCCESS[%2]").arg(portName).arg(Utils::strToHexStr(data.toStdString()).c_str()));
#else
logInfo(tr("PORT:%1 >> CLS RECORD SUCCESS").arg(portName));
#endif
}
//
// 设置锁状态响应
//
void BaseSetupWidget::processSetLockStatusRsp(QString portName, QByteArray data)
{
#ifdef _DEBUG
logDebug(tr("PORT:%1 >> SET LOCK STATUS SUCCESS[%2]").arg(portName).arg(Utils::strToHexStr(data.toStdString()).c_str()));
#else
logInfo(tr("PORT:%1 >> SET LOCK STATUS SUCCESS").arg(portName));
#endif
}
//
// 初始化获取记录定时器
//
void BaseSetupWidget::initRecordTimer()
{
m_recordTimer.stop();
m_recordTimer.setInterval(1000); // 本定时器定时长度可变初始化时暂定1秒后续通过start
connect(&m_recordTimer, SIGNAL(timeout()), this, SLOT(slot_recordTimeout()));
}
//
// 启动获取记录定时器
//
void BaseSetupWidget::startRecordTimer(unsigned int msec)
{
m_recordTimer.start(msec);
}
//
// 停止获取记录定时器
//
void BaseSetupWidget::stopRecordTimer()
{
m_recordTimer.stop();
}
//
// 获取记录定时器超时处理
//
void BaseSetupWidget::slot_recordTimeout()
{
logInfo("文件接收超时");
if(m_recordFlag)
{
stopRecordTimer();
saveRecordToFile();
}
//m_sysStatus = SYS_STATUS_IDLE;
emit get_record_finish(1);
}
/*
void BaseSetupWidget::saveRecordToFile()
{
QString currDateTime = QDateTime::currentDateTime().toString("yyyyMMddhhmmss");
QString fileName = tr("record_%1").arg(currDateTime);
// 打开文件保存路径
m_recordFilePath = QFileDialog::getSaveFileName(
this,
tr("数据文件另存为(Save as)"),
tr("C:/%1").arg(fileName),
tr("Excel files(*.xlsx);;text files(*.csv)"));
if(m_recordFilePath.length() == 0)
{
// 取消保存,相当于取消文件记录了
return;
}
logInfo(tr("记录文件保存路径:%1").arg(m_recordFilePath));
// 开始保存文件,将 m_recordData 中数据存储到文件中
//获取工作簿集合
QAxObject *workbooks = m_excelObject->querySubObject("WorkBooks");
//新建一个工作簿
workbooks->dynamicCall("Add");
//获取当前工作簿
QAxObject *workbook = m_excelObject->querySubObject("ActiveWorkBook");
//获取工作表格集合
QAxObject *worksheets = workbook->querySubObject("Sheets");
//获取当前工作表格1即sheet1
QAxObject *worksheet = worksheets->querySubObject("Item(int)", 1);
//产生数据
QList<QVariant> allRowData;
// 保存标题
QList<QVariant> titleRowData;
for(unsigned int i=0; i<gFieldCount; i++)
{
titleRowData.append(gTagRecordFile[i].fieldName);
}
allRowData.append(QVariant(titleRowData));
for(int row = 1; row <= m_recordData.size(); row++)
{
QList<QVariant> aRowData;
std::string rowData = m_recordData.at(0).toLatin1().toStdString();
//std::string s;
int nPos = 0;
int nLen = 0;
int nIndex = 0;
//{"帧类型", FIELD_TYPE_UCHAR, 1},
nLen = gTagRecordFile[nIndex].fieldLen;
std::string s1 = rowData.substr(nPos, nLen);
nPos += nLen;
char val1 = Utils::strToChar(s1);
aRowData.append(QVariant(Utils::strToChar(s1)));
nIndex++;
//{"序号", FIELD_TYPE_USHORT, 2},
nLen = gTagRecordFile[nIndex].fieldLen;
std::string s2 = rowData.substr(nPos, nLen);
nPos += nLen;
short int val2 = Utils::strToShort(s2);
aRowData.append(QVariant(Utils::strToShort(s2)));
nIndex++;
//{"出厂编号", FIELD_TYPE_STRING, 8},
nLen = gTagRecordFile[nIndex].fieldLen;
std::string s3 = rowData.substr(nPos, nLen);
nPos += nLen;
std::string val3 = s3;
aRowData.append(QVariant(QString::fromStdString(s3)));
nIndex++;
//{"日期", FIELD_TYPE_DATETIME, 7},
nLen = gTagRecordFile[nIndex].fieldLen;
std::string s4 = rowData.substr(nPos, nLen);
logInfo(tr("日期: %1").arg(QString::fromStdString(Utils::strToHexStr(s4))));
nPos += nLen;
std::string val4 = s4;
short int year = Utils::strToShort(s4);
unsigned char month = s4.at(2);
unsigned char day = s4.at(3);
unsigned char hour = s4.at(4);
unsigned char minute = s4.at(5);
unsigned char second = s4.at(6);
aRowData.append(QVariant(tr("%1-%2-%3 %4:%5:%6").arg(year).arg(month).arg(day).arg(hour).arg(minute).arg(second)));
nIndex++;
//{"设备名称", FIELD_TYPE_STRING, 16},
nLen = gTagRecordFile[nIndex].fieldLen;
std::string s5 = rowData.substr(nPos, nLen);
nPos += nLen;
std::string val5 = s5;
aRowData.append(QVariant(QString::fromStdString(s5)));
nIndex++;
//{"设备编号", FIELD_TYPE_STRING, 8},
//{"操作人员", FIELD_TYPE_STRING, 16},
//{"目标扭矩", FIELD_TYPE_UINT, 4},
//{"实际扭矩", FIELD_TYPE_UINT, 4},
//{"螺栓规格等级编号", FIELD_TYPE_USHORT, 2},
//{"目标角度", FIELD_TYPE_USHORT, 2},
//{"实际角度", FIELD_TYPE_USHORT, 2},
//{"档位", FIELD_TYPE_UCHAR, 1},
//{"对应扭矩", FIELD_TYPE_UINT, 4},
//{"选定模式", FIELD_TYPE_UCHAR, 1},
//{"运行时间", FIELD_TYPE_USHORT, 2},
//{"拧紧结果", FIELD_TYPE_UCHAR, 1}
// for(unsigned int i=0; i<gFieldCount; i++)
// {
// s.clear();
// nLen = gTagRecordFile[i].fieldLen;
// s = rowData.toStdString().substr(nPos, nLen);
// nPos += nLen;
// switch(gTagRecordFile[i].fieldType)
// {
// case FIELD_TYPE_STRING:
// aRowData.append(QVariant(QString::fromStdString(s)));
// break;
// case FIELD_TYPE_UCHAR:
// aRowData.append(QVariant(Utils::byteStrToChar(s)));
// break;
// case FIELD_TYPE_USHORT:
// aRowData.append(QVariant(Utils::byteStrToShort(s)));
// break;
// case FIELD_TYPE_UINT:
// aRowData.append(QVariant(Utils::byteStrToInt(s)));
// break;
// case FIELD_TYPE_DATETIME:
// {
// std::string s1;
// int nPos1 = 0;
// int nLen1 = 0;
// s1.clear(); nLen1 = 2; s1 = s.substr(nPos1, nLen1); nPos1 += nLen1; unsigned short dtYear = Utils::byteStrToShort(s);
// s1.clear(); nLen1 = 1; s1 = s.substr(nPos1, nLen1); nPos1 += nLen1; unsigned char dtMonth = Utils::byteStrToChar(s);
// s1.clear(); nLen1 = 1; s1 = s.substr(nPos1, nLen1); nPos1 += nLen1; unsigned char dtDay = Utils::byteStrToChar(s);
// s1.clear(); nLen1 = 1; s1 = s.substr(nPos1, nLen1); nPos1 += nLen1; unsigned char dtHour = Utils::byteStrToChar(s);
// s1.clear(); nLen1 = 1; s1 = s.substr(nPos1, nLen1); nPos1 += nLen1; unsigned char dtMinute = Utils::byteStrToChar(s);
// s1.clear(); nLen1 = 1; s1 = s.substr(nPos1, nLen1); nPos1 += nLen1; unsigned char dtSecond = Utils::byteStrToChar(s);
// QString dateTime = tr("%1-%2-%3 %4:%5:%6").arg(dtYear).arg(dtMonth).arg(dtDay).arg(dtHour).arg(dtMinute).arg(dtSecond);
// aRowData.append(QVariant(dateTime));
// }
// break;
// default:
// aRowData.append(QVariant(""));
// break;
// }
// }
// for(int column = 1; column <= 2; column++) {
// aRowData.append(QVariant(row*column));
// }
allRowData.append(QVariant(aRowData));
}
//选取范围
//QAxObject *range = worksheet->querySubObject("Range(const QString)", "A1:Q1");
QAxObject *range = worksheet->querySubObject("Range(const QString)", tr("A1:Q%1").arg(m_recordData.size() + 1));
//批量写入
range->dynamicCall("SetValue(const QVariant&)", QVariant(allRowData));
//设置字体大小
//range->querySubObject("Font")->setProperty("Size", 30);
//获取单元格
//QAxObject *cell = worksheet->querySubObject("Cells(int, int)", 1, 1);
//储存一个字符串数据至表格
//cell->dynamicCall("setValue(const QVariant&)", QVariant("abc"));
//读取单元格数据
//QString str = cell->dynamicCall("Value2()").toString();
//qDebug()<<"The value of cell is "<< str <<endl;
//调整行高
//worksheet->querySubObject("Range(const QString&)", "3:4")->setProperty("RowHeight", 60);
//worksheet->querySubObject("Range(const QString&)", "j1")->setProperty("ColumnWidth", 80);
//保存至文件注意一定要用QDir::toNativeSeparators将路径中的"/"转换为"\",不然一定保存不了。
workbook->dynamicCall("SaveAs(const QString&)", QDir::toNativeSeparators(m_recordFilePath));
workbook->dynamicCall("Close(Boolean)", true);
}
*/
void BaseSetupWidget::saveToXlsx()
{
QXlsx::Document xlsx;
//产生数据
//QList<QVariant> allRowData;
// 保存标题
//QList<QVariant> titleRowData;
// 从1开始忽略第一个
QXlsx::CellRange range(1,1,1,18);
xlsx.setColumnWidth(range,13);
xlsx.setColumnWidth(4,16);
QXlsx::Format format;
format.setFontSize(11);
format.setFontName(QStringLiteral("Calibri"));
format.setVerticalAlignment(QXlsx::Format::AlignVCenter);
format.setHorizontalAlignment(QXlsx::Format::AlignHCenter);
for(unsigned int i=1; i<gFieldCount; i++)
{
xlsx.write(tr("%1%2").arg((char)('A' + (i - 1))).arg(1), gTagRecordFile[i].fieldName,format);
xlsx.write(tr("%1%2").arg((char)('A' + (i - 1))).arg(2), gTagRecordFileEng[i].fieldName,format);
}
QString unit_Pressure,unit_Torque;
for(int row = 1; row <= m_recordData.size(); row++)
{
int cRow = row + 2;
std::string rowData = m_recordData.at(row-1).toLatin1().toStdString();
logInfo(tr("data[%1]").arg(QString::fromStdString(Utils::strToHexStr(rowData))));
std::string s;
int nPos = 0;
int nLen = 0;
for(unsigned int i=0; i<gFieldCount; i++)
{
s.clear();
if(i == 8)
{
unsigned char unit1 = Utils::byteStrToChar(rowData.substr(nPos, 1));
nPos +=1;
unsigned char unit2 = Utils::byteStrToChar(rowData.substr(nPos, 1));
nPos +=1;
switch (unit1) {
case 0:
unit_Pressure = "Bar";
break;
case 1:
unit_Pressure = "Mpa";
break;
case 2:
unit_Pressure = "Psi";
break;
default:
break;
}
switch (unit2) {
case 0:
unit_Torque = "N.m";
break;
case 1:
unit_Torque = "Ft.lbs";
break;
default:
break;
}
}
nLen = gTagRecordFile[i].fieldLen;
s = rowData.substr(nPos, nLen);
nPos += nLen;
// 忽略第一个
if(i==0)
{
continue;
}
char cCol = 'A' + (i - 1);
QString sPos = tr("%1%2").arg(cCol).arg(cRow);
switch(gTagRecordFile[i].fieldType)
{
case FIELD_TYPE_STRING:
xlsx.write(sPos, QVariant(QString::fromStdString(s)),format);
//aRowData.append(QVariant(QString::fromStdString(s)));
break;
case FIELD_TYPE_UCHAR:
{
unsigned char param = Utils::byteStrToChar(s);
QString strParam;
if(i==16)
{
switch (param) {
case 1:
strParam = "Torque/扭矩";
break;
case 2:
strParam = "Bolt/螺栓";
break;
case 3:
strParam = "Gear/档位";
break;
case 4:
strParam = "Angle/角度";
break;
case 5:
strParam = "Sensor/传感器";
break;
default:
break;
}
}else if (i==17)
{
switch (param) {
case 0:
if (m_currType == m_spannerType)
{
strParam = "手动/HAND";
}else{
strParam = "";
}
break;
case 1:
if (m_currType == m_spannerType)
{
strParam = "自动/AUTO";
}else{
strParam = "";
}
break;
default:
break;
}
}else if (i==18)
{
switch (param) {
case 0:
strParam = "×";
break;
case 1:
strParam = "";
break;
default:
break;
}
}else
{
strParam = QString::number(param);
}
xlsx.write(sPos, QVariant(strParam),format);
// qDebug()<<strParam;
break;
//aRowData.append(QVariant(Utils::byteStrToChar(s)));
}
case FIELD_TYPE_USHORT:
if(i==8)
{
xlsx.write(sPos, QVariant(QString("%1 %2").arg(Utils::byteStrToShort(s)).arg(unit_Pressure)),format);
}else
xlsx.write(sPos, QVariant(Utils::byteStrToShort(s)),format);
//aRowData.append(QVariant(Utils::byteStrToShort(s)));
break;
case FIELD_TYPE_UINT:
if(i==9||i==10)
{
xlsx.write(sPos, QVariant(QString("%1 %2").arg(Utils::byteStrToInt(s)).arg(unit_Torque)),format);
}else
{
xlsx.write(sPos, QVariant(Utils::byteStrToInt(s)),format);
}
//aRowData.append(QVariant(Utils::byteStrToInt(s)));
break;
case FIELD_TYPE_DATETIME:
{
short int year = Utils::strToShort(s);
unsigned char month = s.at(2);
unsigned char day = s.at(3);
unsigned char hour = s.at(4);
unsigned char minute = s.at(5);
unsigned char second = s.at(6);
QString dateTime = tr("%1-%2-%3 %4:%5:%6").arg(year).arg(month).arg(day).arg(hour).arg(minute).arg(second);
xlsx.write(sPos, QVariant(dateTime),format);
//aRowData.append(QVariant(dateTime));
}
break;
default:
xlsx.write(sPos, QVariant(""),format);
break;
}
}
}
xlsx.saveAs(m_recordFilePath);
}
void BaseSetupWidget::saveToCsv()
{
QFile file(m_recordFilePath);
if (!file.open(QIODevice::WriteOnly|QIODevice::Text))
{
QMessageBox::warning(this, "warning", tr("文件保存失败!"), QMessageBox::Ok, QMessageBox::Ok);
return;
}
std::stringstream ssTitle;
// 从1开始忽略第一个
for(unsigned int i=1; i<gFieldCount; i++)
{
ssTitle << gTagRecordFile[i].fieldName.toStdString() << ",";
}
ssTitle << std::endl;
file.write(ssTitle.str().c_str(), ssTitle.str().length());
for(int row = 1; row <= m_recordData.size(); row++)
{
std::string rowData = m_recordData.at(0).toLatin1().toStdString();
std::stringstream ss;
logInfo(tr("data[%1]").arg(QString::fromStdString(Utils::strToHexStr(rowData))));
std::string s;
int nPos = 0;
int nLen = 0;
for(unsigned int i=0; i<gFieldCount; i++)
{
s.clear();
nLen = gTagRecordFile[i].fieldLen;
s = rowData.substr(nPos, nLen);
nPos += nLen;
// 忽略第一个
if(i == 0)
{
continue;
}
switch(gTagRecordFile[i].fieldType)
{
case FIELD_TYPE_STRING:
ss << s << ",";
break;
case FIELD_TYPE_UCHAR:
ss << (Utils::strToChar(s) - '\0') << ",";
break;
case FIELD_TYPE_USHORT:
ss << Utils::strToShort(s) << ",";
break;
case FIELD_TYPE_UINT:
ss << Utils::strToInt(s) << ",";
break;
case FIELD_TYPE_DATETIME:
{
short int year = Utils::strToShort(s);
unsigned char month = s.at(2);
unsigned char day = s.at(3);
unsigned char hour = s.at(4);
unsigned char minute = s.at(5);
unsigned char second = s.at(6);
QString dateTime = tr("%1-%2-%3 %4:%5:%6").arg(year).arg(month).arg(day).arg(hour).arg(minute).arg(second);
ss << dateTime.toStdString() << ",";
}
break;
default:
ss << ",";
break;
}
}
ss << std::endl;
file.write(ss.str().c_str(), ss.str().length());
}
file.close();
}
//
// 保存记录到文件
//
void BaseSetupWidget::saveRecordToFile()
{
QString currDateTime = QDateTime::currentDateTime().toString("yyyyMMddhhmmss");
QString fileName = tr("record_%1").arg(currDateTime);
// 打开文件保存路径
m_recordFilePath = QFileDialog::getSaveFileName(
this,
tr("数据文件另存为(Save as)"),
tr("C:/%1").arg(fileName),
tr("Excel files(*.xlsx);;text files(*.csv)"));
if(m_recordFilePath.length() == 0)
{
// 取消保存,相当于取消文件记录了
return;
}
logInfo(tr("记录文件保存路径:%1").arg(m_recordFilePath));
QFileInfo fileInfo(m_recordFilePath);
if(fileInfo.suffix().toLower().compare("xlsx") == 0)
{
saveToXlsx();
}
else // 默认均保存为csv格式 // if(fileInfo.suffix().toLower().compare("csv") == 0)
{
saveToCsv();
}
QMessageBox::warning(this, "Warning!", "文件保存完毕!", QMessageBox::Ok, QMessageBox::Ok);
}