2025-12-26T17:29:18
This commit is contained in:
parent
0583d5f84f
commit
44fc93eb4e
BIN
experiment_data/sample_data/new_2025_12_26_10_25_03.xlsx
Normal file
BIN
experiment_data/sample_data/new_2025_12_26_10_25_03.xlsx
Normal file
Binary file not shown.
BIN
experiment_data/sample_data/new_2025_12_26_10_25_31.xlsx
Normal file
BIN
experiment_data/sample_data/new_2025_12_26_10_25_31.xlsx
Normal file
Binary file not shown.
BIN
experiment_data/sample_data/new_2025_12_26_10_26_11.xlsx
Normal file
BIN
experiment_data/sample_data/new_2025_12_26_10_26_11.xlsx
Normal file
Binary file not shown.
BIN
experiment_data/sample_data/new_2025_12_26_10_26_45.xlsx
Normal file
BIN
experiment_data/sample_data/new_2025_12_26_10_26_45.xlsx
Normal file
Binary file not shown.
BIN
experiment_data/sample_data/new_2025_12_26_10_54_03.xlsx
Normal file
BIN
experiment_data/sample_data/new_2025_12_26_10_54_03.xlsx
Normal file
Binary file not shown.
BIN
experiment_data/sample_data/new_2025_12_26_10_59_00.xlsx
Normal file
BIN
experiment_data/sample_data/new_2025_12_26_10_59_00.xlsx
Normal file
Binary file not shown.
BIN
experiment_data/sample_data/new_2025_12_26_11_22_19.xlsx
Normal file
BIN
experiment_data/sample_data/new_2025_12_26_11_22_19.xlsx
Normal file
Binary file not shown.
BIN
experiment_data/sample_data/new_2025_12_26_16_34_45.xlsx
Normal file
BIN
experiment_data/sample_data/new_2025_12_26_16_34_45.xlsx
Normal file
Binary file not shown.
BIN
experiment_data/sample_data/new_2025_12_26_16_35_51.xlsx
Normal file
BIN
experiment_data/sample_data/new_2025_12_26_16_35_51.xlsx
Normal file
Binary file not shown.
BIN
experiment_data/sample_data/new_2025_12_26_17_25_52.xlsx
Normal file
BIN
experiment_data/sample_data/new_2025_12_26_17_25_52.xlsx
Normal file
Binary file not shown.
33
src/.vscode/settings.json
vendored
33
src/.vscode/settings.json
vendored
@ -5,6 +5,37 @@
|
||||
"string": "cpp",
|
||||
"string_view": "cpp",
|
||||
"deque": "cpp",
|
||||
"vector": "cpp"
|
||||
"vector": "cpp",
|
||||
"list": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"cmath": "cpp",
|
||||
"complex": "cpp",
|
||||
"atomic": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"chrono": "cpp",
|
||||
"bitset": "cpp",
|
||||
"exception": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"memory": "cpp",
|
||||
"optional": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"functional": "cpp",
|
||||
"fstream": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"mutex": "cpp",
|
||||
"new": "cpp",
|
||||
"ostream": "cpp",
|
||||
"ratio": "cpp",
|
||||
"sstream": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"system_error": "cpp",
|
||||
"thread": "cpp",
|
||||
"tuple": "cpp",
|
||||
"typeinfo": "cpp"
|
||||
}
|
||||
}
|
||||
@ -9,7 +9,7 @@ CONFIG+=precompile_header
|
||||
PRECOMPILED_HEADER=stable.h
|
||||
|
||||
#
|
||||
VERSION = 1.4.0
|
||||
VERSION = 1.3.9
|
||||
# 设置目标文件名,包含版本号
|
||||
TARGET = DSCAnalysisTool_$${VERSION}
|
||||
|
||||
|
||||
@ -96,7 +96,10 @@ namespace Global {
|
||||
QVector<Phase> phaseVtr;
|
||||
|
||||
ExperimentInfo()
|
||||
: sampleName("new"), sampleWeight("0"), date("20250101"), experimentor("experimentor") {}
|
||||
: sampleName("new"),
|
||||
sampleWeight("0"),
|
||||
date("20250101"),
|
||||
experimentor("experimentor") {}
|
||||
};
|
||||
|
||||
struct PhaseTotalInfo {
|
||||
@ -179,6 +182,7 @@ extern QString _smoothnessFileName;
|
||||
extern QStringList _fileList;
|
||||
void updateFileList();
|
||||
bool isFileExist(const QString &fileName);
|
||||
|
||||
|
||||
}; // namespace Global
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#ifndef LOGGER_H
|
||||
#define LOGGER_H
|
||||
|
||||
#include "easylogging++.h"
|
||||
#include "../thirdparty/easylogging/easylogging++.h"
|
||||
|
||||
#define logde LOG(DEBUG)
|
||||
#define loger LOG(ERROR)
|
||||
@ -17,4 +17,4 @@ public:
|
||||
static Logger *instance();
|
||||
};
|
||||
|
||||
#endif // LOGGER_H
|
||||
#endif // LOGGER_H
|
||||
@ -15,7 +15,7 @@
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// system("chcp 65001");
|
||||
// system("chcp 65001");
|
||||
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
|
||||
QTextCodec::setCodecForLocale(codec);
|
||||
|
||||
@ -27,6 +27,7 @@ int main(int argc, char *argv[])
|
||||
// 启用高DPI支持
|
||||
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); // 启用高DPI缩放
|
||||
|
||||
QApplication a(argc, argv);
|
||||
|
||||
logde<<"version:"<<a.applicationVersion().toStdString();
|
||||
|
||||
@ -9,107 +9,104 @@
|
||||
|
||||
namespace DataParser
|
||||
{
|
||||
bool commonDataParser(const QByteArray &ba, CommonData &cd)
|
||||
{
|
||||
const char *charArray = ba.data();
|
||||
bool commonDataParser(const QByteArray &ba, CommonData &cd)
|
||||
{
|
||||
const char *charArray = ba.data();
|
||||
|
||||
// 判断前两个字节是否为 0xA5 和 0x5A (小端格式)
|
||||
if (static_cast<unsigned char>(charArray[0]) == 0xA5 &&
|
||||
// 判断前两个字节是否为 0xA5 和 0x5A (小端格式)
|
||||
if (static_cast<unsigned char>(charArray[0]) == 0xA5 &&
|
||||
static_cast<unsigned char>(charArray[1]) == 0x5A)
|
||||
{
|
||||
// std::cout << "前两个字节是 0x5AA5 (小端)" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
// std::cout << "前两个字节不是 0x5AA5 (小端)" << std::endl;
|
||||
qDebug() << "header failed.";
|
||||
return false;
|
||||
{
|
||||
// std::cout << "前两个字节是 0x5AA5 (小端)" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
// std::cout << "前两个字节不是 0x5AA5 (小端)" << std::endl;
|
||||
qDebug() << "header failed.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (static_cast<unsigned char>(charArray[3]) != 0x83)
|
||||
{
|
||||
qDebug() << "mark failed.";
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(&cd, charArray + 6, sizeof(CommonData));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (static_cast<unsigned char>(charArray[3]) != 0x83)
|
||||
QByteArray setExperimentInfo(const QVector<Phase> &vtr, const QByteArray initBa)
|
||||
{
|
||||
qDebug() << "mark failed.";
|
||||
return false;
|
||||
// const int phaseLength = sizeof(Phase);
|
||||
const int phaseLength = PHASE_BYTE_SIZE;
|
||||
|
||||
const int phaseArrayLength = vtr.size() * phaseLength;
|
||||
char phaseArray[300] = {};
|
||||
int offset = 0;
|
||||
|
||||
for (const Phase &phase : vtr)
|
||||
{
|
||||
memcpy(phaseArray + offset, &phase, sizeof(Phase));
|
||||
offset += phaseLength;
|
||||
}
|
||||
|
||||
// int totalDataLength = 0;
|
||||
char totalData[300] = {};
|
||||
|
||||
u16 header = 0x5aa5;
|
||||
memcpy(totalData, (char *)&header, sizeof(u16));
|
||||
|
||||
// command + addr + data + crc
|
||||
totalData[2] = 1 + 2 + phaseArrayLength + 2 + 2;
|
||||
|
||||
totalData[3] = 0x82;
|
||||
|
||||
u16 address = 0x0050;
|
||||
memcpy(totalData + 4, (char *)&address, sizeof(u16));
|
||||
|
||||
memcpy(totalData + 6, phaseArray, phaseArrayLength);
|
||||
|
||||
memcpy(totalData + 6 + phaseArrayLength, initBa.data(), 2);
|
||||
|
||||
//
|
||||
char data[300] = {};
|
||||
|
||||
data[0] = 0x82;
|
||||
|
||||
// u16 address = 0x0050;
|
||||
memcpy(data + 1, (char *)&address, sizeof(u16));
|
||||
|
||||
memcpy(data + 3, phaseArray, phaseArrayLength);
|
||||
// initial data
|
||||
memcpy(data + 3 + phaseArrayLength, initBa.data(), 2);
|
||||
|
||||
u16 crc = modbusCRC16((u8 *)data, 3 + phaseArrayLength + 2);
|
||||
//
|
||||
memcpy(totalData + 6 + phaseArrayLength + 2, (char *)&crc, sizeof(u16));
|
||||
|
||||
// header + phase data + initial data + crc.
|
||||
return QByteArray(totalData, 6 + phaseArrayLength + 2 + 2);
|
||||
}
|
||||
|
||||
memcpy(&cd, charArray + 6, sizeof(CommonData));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
QByteArray setExperimentInfo(const QVector<Phase> &vtr,const QByteArray initBa)
|
||||
{
|
||||
// const int phaseLength = sizeof(Phase);
|
||||
const int phaseLength = PHASE_BYTE_SIZE;
|
||||
|
||||
const int phaseArrayLength = vtr.size() * phaseLength;
|
||||
char phaseArray[300] = {};
|
||||
int offset = 0;
|
||||
|
||||
for (const Phase &phase : vtr)
|
||||
QByteArray setDeviceStartStop(const DeviceStartMode mode)
|
||||
{
|
||||
memcpy(phaseArray + offset, &phase, sizeof(Phase));
|
||||
offset += phaseLength;
|
||||
}
|
||||
|
||||
//
|
||||
// int totalDataLength = 0;
|
||||
char totalData[300] = {};
|
||||
|
||||
u16 header = 0x5aa5;
|
||||
memcpy(totalData, (char *)&header, sizeof(u16));
|
||||
|
||||
// command + addr + data + crc
|
||||
totalData[2] = 1 + 2 + phaseArrayLength + 2 + 2;
|
||||
|
||||
totalData[3] = 0x82;
|
||||
|
||||
u16 address = 0x0050;
|
||||
memcpy(totalData + 4, (char *)&address, sizeof(u16));
|
||||
|
||||
memcpy(totalData + 6, phaseArray, phaseArrayLength);
|
||||
|
||||
memcpy(totalData + 6 + phaseArrayLength,initBa.data(),2);
|
||||
|
||||
//
|
||||
char data[300] = {};
|
||||
|
||||
data[0] = 0x82;
|
||||
|
||||
// u16 address = 0x0050;
|
||||
memcpy(data + 1, (char *)&address, sizeof(u16));
|
||||
|
||||
memcpy(data + 3, phaseArray, phaseArrayLength);
|
||||
// initial data
|
||||
memcpy(data + 3 + phaseArrayLength,initBa.data(),2);
|
||||
|
||||
u16 crc = modbusCRC16((u8 *)data, 3 + phaseArrayLength + 2);
|
||||
//
|
||||
memcpy(totalData + 6 + phaseArrayLength + 2, (char *)&crc, sizeof(u16));
|
||||
|
||||
// header + phase data + initial data + crc.
|
||||
return QByteArray(totalData, 6 + phaseArrayLength + 2 + 2);
|
||||
}
|
||||
|
||||
QByteArray setDeviceStartStop(const DeviceStartMode mode)
|
||||
{
|
||||
#if 1
|
||||
SerialPortProtocol spp;
|
||||
spp.head = FRANE_HEAD;
|
||||
spp.len = 1 + 2 + 1 + 2;
|
||||
spp.cmd = WRITE_CMD;
|
||||
spp.addr = 0x002c;
|
||||
spp.data_buf[0] = mode;
|
||||
SerialPortProtocol spp;
|
||||
spp.head = FRANE_HEAD;
|
||||
spp.len = 1 + 2 + 1 + 2;
|
||||
spp.cmd = WRITE_CMD;
|
||||
spp.addr = 0x002c;
|
||||
spp.data_buf[0] = mode;
|
||||
|
||||
int sppValidLength = 6 + 1;
|
||||
int sppValidLength = 6 + 1;
|
||||
|
||||
u8 *dataPtr = (u8 *)&spp;
|
||||
u16 crc = modbusCRC16((u8 *)(dataPtr + 3), 4);
|
||||
u8 *dataPtr = (u8 *)&spp;
|
||||
u16 crc = modbusCRC16((u8 *)(dataPtr + 3), 4);
|
||||
|
||||
return QByteArray((char *)&spp, sppValidLength) +
|
||||
QByteArray((char *)&crc, 2);
|
||||
return QByteArray((char *)&spp, sppValidLength) +
|
||||
QByteArray((char *)&crc, 2);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
@ -138,73 +135,73 @@ QByteArray setDeviceStartStop(const DeviceStartMode mode)
|
||||
|
||||
return QByteArray(data,length);
|
||||
#endif
|
||||
}
|
||||
|
||||
void experimentalStateSwitching(const CommonData &cd)
|
||||
{
|
||||
// Switch the software mode accord to the serial port data.
|
||||
switch(cd.run_type){
|
||||
case DeviceRunStatus::Heat:
|
||||
case DeviceRunStatus::ConstantTemp:
|
||||
Global::_mode = Global::Mode::Experiment;
|
||||
break;
|
||||
case DeviceRunStatus::Idle:
|
||||
case DeviceRunStatus::Cooling:
|
||||
Global::_mode = Global::Mode::Analysis;
|
||||
|
||||
break;
|
||||
default:break;
|
||||
}
|
||||
|
||||
void experimentalStateSwitching(const CommonData &cd)
|
||||
{
|
||||
// Switch the software mode accord to the serial port data.
|
||||
switch (cd.run_type)
|
||||
{
|
||||
case DeviceRunStatus::Heat:
|
||||
case DeviceRunStatus::ConstantTemp:
|
||||
Global::_mode = Global::Mode::Experiment;
|
||||
break;
|
||||
case DeviceRunStatus::Idle:
|
||||
case DeviceRunStatus::Cooling:
|
||||
Global::_mode = Global::Mode::Analysis;
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
logde<<"phase:"<<(int)cd.current_phase;
|
||||
logde<<"run type:"<<(int)cd.run_type;
|
||||
logde<<"software mode:"<<Global::_mode;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
unsigned short modbusCRC16(unsigned char *data, unsigned short length)
|
||||
{
|
||||
unsigned short crc = 0xFFFF;
|
||||
unsigned char i;
|
||||
for (unsigned short j = 0; j < length; j++)
|
||||
unsigned short modbusCRC16(unsigned char *data, unsigned short length)
|
||||
{
|
||||
crc ^= (unsigned short)data[j];
|
||||
for (i = 0; i < 8; i++)
|
||||
unsigned short crc = 0xFFFF;
|
||||
unsigned char i;
|
||||
for (unsigned short j = 0; j < length; j++)
|
||||
{
|
||||
if (crc & 0x0001)
|
||||
crc ^= (unsigned short)data[j];
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
crc = (crc >> 1) ^ 0xA001;
|
||||
}
|
||||
else
|
||||
{
|
||||
crc = crc >> 1;
|
||||
if (crc & 0x0001)
|
||||
{
|
||||
crc = (crc >> 1) ^ 0xA001;
|
||||
}
|
||||
else
|
||||
{
|
||||
crc = crc >> 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
// CRC结果低字节在前,高字节在后
|
||||
return crc;
|
||||
}
|
||||
|
||||
// 请求实验参数
|
||||
QByteArray inquirePhaseInfo()
|
||||
{
|
||||
SerialPortProtocol spp;
|
||||
spp.head = FRANE_HEAD;
|
||||
spp.cmd = READ_CMD;
|
||||
spp.addr = 0x0050;
|
||||
spp.len = 6;
|
||||
//
|
||||
spp.data_buf[0] = PHASE_BYTE_SIZE * 6 + 2;
|
||||
//
|
||||
u8 *dataPtr = (u8 *)&spp;
|
||||
u16 crc = modbusCRC16((u8 *)(dataPtr + 3), 4);
|
||||
//
|
||||
int sppValidLength = 6 + 1;
|
||||
return QByteArray((char *)&spp, sppValidLength) +
|
||||
QByteArray((char *)&crc, 2);
|
||||
}
|
||||
// CRC结果低字节在前,高字节在后
|
||||
return crc;
|
||||
}
|
||||
|
||||
QByteArray inquirePhaseInfo()
|
||||
{
|
||||
SerialPortProtocol spp;
|
||||
spp.head = FRANE_HEAD;
|
||||
spp.cmd = READ_CMD;
|
||||
spp.addr = 0x0050;
|
||||
spp.len = 6;
|
||||
//
|
||||
spp.data_buf[0] = PHASE_BYTE_SIZE * 6 + 2;
|
||||
//
|
||||
u8 *dataPtr = (u8 *)&spp;
|
||||
u16 crc = modbusCRC16((u8 *)(dataPtr + 3), 4);
|
||||
//
|
||||
int sppValidLength = 6 + 1;
|
||||
return QByteArray((char *)&spp, sppValidLength) +
|
||||
QByteArray((char *)&crc, 2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
@ -21,3 +21,8 @@ unsigned short modbusCRC16(unsigned char *data,unsigned short length);
|
||||
}
|
||||
|
||||
#endif // DATAPARSER_H
|
||||
|
||||
/**
|
||||
中油资本
|
||||
孚日股份
|
||||
*/
|
||||
|
||||
@ -3,11 +3,11 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#define FRANE_HEAD 0x5AA5 //枕头
|
||||
#define FRANE_HEAD 0x5AA5 //帧头
|
||||
#define WRITE_CMD 0x82 //写指令
|
||||
#define READ_CMD 0x83 //读指令
|
||||
|
||||
#define PHASE_START_ADDR 0X0050
|
||||
#define PHASE_START_ADDR 0X0050
|
||||
#define PHASE_BYTE_SIZE 12
|
||||
|
||||
#pragma pack(push)
|
||||
@ -35,13 +35,13 @@ typedef struct com_protocol
|
||||
uint8_t cmd;
|
||||
uint16_t addr;
|
||||
uint8_t data_buf[256];
|
||||
}SerialPortProtocol;
|
||||
} SerialPortProtocol;
|
||||
|
||||
typedef enum gas_type {
|
||||
NC,
|
||||
N2,
|
||||
O2
|
||||
}GasType;
|
||||
} GasType;
|
||||
|
||||
typedef struct control_data
|
||||
{
|
||||
@ -50,7 +50,7 @@ typedef struct control_data
|
||||
float temp_flow;
|
||||
uint16_t constant_temp_time_min;
|
||||
enum gas_type gas; // uint8_t
|
||||
}Phase;
|
||||
} Phase;
|
||||
|
||||
struct pid_data
|
||||
{
|
||||
@ -59,6 +59,7 @@ struct pid_data
|
||||
float kd;
|
||||
};
|
||||
|
||||
#if 0
|
||||
typedef struct com_data
|
||||
{
|
||||
uint8_t run_type; //0,运行状态
|
||||
@ -99,6 +100,52 @@ typedef struct com_data
|
||||
float enthalpy_equation_b; //热焓方程式系数b
|
||||
float enthalpy_equation_c; //热焓方程式系数c
|
||||
} CommonData;
|
||||
#endif
|
||||
|
||||
using rt_uint8_t = uint8_t;
|
||||
|
||||
typedef struct com_data
|
||||
{
|
||||
rt_uint8_t run_type; //0,运行状态
|
||||
rt_uint8_t current_phase; //1,当前阶段
|
||||
float add_run_time; //2,累计运行时间
|
||||
float add_constan_temp_time; //6,当前阶段恒温时间
|
||||
double sample_temp; //A,样品温度
|
||||
double dsc; //12,热流
|
||||
double temp_flow; //1a,升温速率
|
||||
float cold_temp; //22,冷端温度
|
||||
rt_uint8_t hardware_err; //26,硬件错误
|
||||
rt_uint8_t current_gas; //27,当前气氛
|
||||
float auto_pid_temp_flow; //28,自整定升温速率
|
||||
rt_uint8_t run_mode; //2c,启动模式
|
||||
rt_uint8_t reserve_buf[35]; //2d-4f,保留
|
||||
struct control_data phase_data[6];//50-97,阶段控制数据
|
||||
rt_uint8_t meas_type; //98,测试类型
|
||||
rt_uint8_t init_gas; //99, 初始气氛
|
||||
struct pid_data temp_flow_pid_low;//9a-a5,升温速率 低pid
|
||||
struct pid_data temp_flow_pid_high;//a6-B1,升温速率 高pid
|
||||
float cold_temp_cali_standard; //B2,冷端标准温度
|
||||
float cold_temp_cali_meas; //B6,冷端测量温度
|
||||
rt_uint8_t cold_cali_flag; //BA,冷端温度计算
|
||||
float cold_temp_slope; //BB,冷端温度倍率
|
||||
float sample_temp_calilow_standard;//BF,样品标准温度低倍率
|
||||
float sample_temp_calilow_meas; //C3,样品测量温度低倍率
|
||||
rt_uint8_t sample_temp_cali_low_flag;//C7,样品温度计算低倍率
|
||||
float sample_temp_slope_low; //C8,样品温度低倍率低倍率
|
||||
float sample_temp_calimid_standard;//CC,样品标准温度中倍率
|
||||
float sample_temp_calimid_meas; //D0,样品测量温度中倍率
|
||||
rt_uint8_t sample_temp_cali_mid_flag;//D4,样品温度计算中倍率
|
||||
float sample_temp_slope_middle; //D5,样品温度中倍率
|
||||
float sample_temp_calihigh_standard;//D9,样品标准温度高倍率
|
||||
float sample_temp_calihigh_meas; //DD样品测量温度高倍率
|
||||
rt_uint8_t sample_temp_cali_high_flag; //E1样品温度计算高倍率
|
||||
float sample_temp_slope_high; //E2样品温度高倍率
|
||||
rt_uint8_t cali_data_backup; //E6标定数据备份
|
||||
float enthalpy_equation_a; //热焓方程式系数a
|
||||
float enthalpy_equation_b; //热焓方程式系数b
|
||||
float enthalpy_equation_c; //热焓方程式系数c
|
||||
|
||||
}CommonData;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
@ -15,16 +15,17 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
const u16 conVid = 1155; // 0x0483
|
||||
const u16 conPid = 22336; // 0x5740
|
||||
const u16 conVid = 1155; // 0x0483
|
||||
const u16 conPid = 22336; // 0x5740
|
||||
|
||||
SerialPort::SerialPort(QObject *parent)
|
||||
: QObject(parent), _sp(new QSerialPort(this)),
|
||||
_portCheckTimer(new QTimer(this)) {
|
||||
_portCheckTimer(new QTimer(this))
|
||||
{
|
||||
//
|
||||
connect(_portCheckTimer, &QTimer::timeout,
|
||||
this, &SerialPort::slotPortCheck);
|
||||
_portCheckTimer->start(1000); // 每秒检测一次
|
||||
_portCheckTimer->start(1000); // 每秒检测一次
|
||||
|
||||
// displayPortInfo();
|
||||
|
||||
@ -77,12 +78,14 @@ SerialPort::SerialPort(QObject *parent)
|
||||
#endif
|
||||
}
|
||||
|
||||
SerialPort *SerialPort::instance() {
|
||||
SerialPort *SerialPort::instance()
|
||||
{
|
||||
static SerialPort ins;
|
||||
return &ins;
|
||||
}
|
||||
|
||||
SerialPort::~SerialPort() {
|
||||
SerialPort::~SerialPort()
|
||||
{
|
||||
logde << "serialport destructor.";
|
||||
|
||||
closeSp();
|
||||
@ -95,9 +98,11 @@ SerialPort::~SerialPort() {
|
||||
_portCheckTimer = nullptr;
|
||||
}
|
||||
|
||||
void SerialPort::slotReadData() {
|
||||
void SerialPort::slotReadData()
|
||||
{
|
||||
QByteArray ba = _sp->readAll();
|
||||
if (ba.size() == 0) {
|
||||
if (ba.size() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@ -107,42 +112,74 @@ void SerialPort::slotReadData() {
|
||||
#endif
|
||||
|
||||
SerialPortProtocol *spp = (SerialPortProtocol *)ba.data();
|
||||
if (FRANE_HEAD != spp->head) {
|
||||
if (FRANE_HEAD != spp->head)
|
||||
{
|
||||
logde << "Data header error.";
|
||||
return;
|
||||
}
|
||||
|
||||
// phase setting data
|
||||
if (spp->addr == PHASE_START_ADDR) {
|
||||
// 实验阶段数据设置
|
||||
if (spp->addr == PHASE_START_ADDR)
|
||||
{
|
||||
emit sigSendPhaseInfo(ba);
|
||||
return;
|
||||
}
|
||||
|
||||
int dataLength = spp->len - 5;
|
||||
|
||||
// 非实验阶段数据解析
|
||||
CommonData cd;
|
||||
u8 *cdPtr = (u8 *)&cd;
|
||||
u8 *cdPtr = (u8 *)&cd;
|
||||
memcpy(cdPtr + spp->addr, spp->data_buf, dataLength);
|
||||
|
||||
if (WRITE_CMD == spp->cmd) {
|
||||
// 写指令
|
||||
if (WRITE_CMD == spp->cmd)
|
||||
{
|
||||
logde << "write cmd...";
|
||||
|
||||
QString hexData = ba.toHex(' '); // ' ' 作为分隔符,可选参数
|
||||
logde << "receive info (hex):" << hexData.toStdString();
|
||||
|
||||
logde << "addr:" << spp->addr;
|
||||
logde << "init gas type:" << (int)cd.init_gas;
|
||||
|
||||
commonDataParser(dataLength, spp->addr, cd);
|
||||
} else if (READ_CMD == spp->cmd) {
|
||||
|
||||
logde << "meas type:" << (int)cd.meas_type;
|
||||
logde << "init gas:" << (int)cd.init_gas;
|
||||
|
||||
if(spp->addr == 0x99){
|
||||
logde<<"init gas type:"<<(int)spp->data_buf[0];
|
||||
Global::_experimentInfo.initialAtmosPhere = (GasType)spp->data_buf[0];
|
||||
}
|
||||
}
|
||||
else if (READ_CMD == spp->cmd)
|
||||
{
|
||||
// 读指令
|
||||
// logde<<"read cmd...";
|
||||
|
||||
// DataParser::experimentalStateSwitching(cd);
|
||||
|
||||
updateStatus(cd);
|
||||
|
||||
if (spp->addr == 0) {
|
||||
if (Global::Mode::Experiment == Global::_mode) {
|
||||
if (spp->addr == 0)
|
||||
{
|
||||
if (Global::Mode::Experiment == Global::_mode)
|
||||
{
|
||||
emit sigSendCommonData(cd);
|
||||
}
|
||||
// emit sigSendCommonDataToRealDataForm(cd);
|
||||
} else {
|
||||
QString hexData = ba.toHex(' '); // ' ' 作为分隔符,可选参数
|
||||
}
|
||||
else
|
||||
{
|
||||
QString hexData = ba.toHex(' '); // ' ' 作为分隔符,可选参数
|
||||
logde << "receive info (hex):" << hexData.toStdString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SerialPort::updateStatus(const CommonData &cd) {
|
||||
void SerialPort::updateStatus(const CommonData &cd)
|
||||
{
|
||||
#if 0
|
||||
// logde<<"phase:"<<(int)cd.current_phase;
|
||||
// logde<<"run type:"<<(int)cd.run_type;
|
||||
@ -150,32 +187,37 @@ void SerialPort::updateStatus(const CommonData &cd) {
|
||||
#endif
|
||||
|
||||
// Switch the software mode accord to the serial port data.
|
||||
switch (cd.run_type) {
|
||||
case DeviceRunStatus::Heat:
|
||||
case DeviceRunStatus::ConstantTemp:
|
||||
if (Global::_mode != Global::Mode::Experiment) {
|
||||
Global::_mode = Global::Mode::Experiment;
|
||||
}
|
||||
break;
|
||||
case DeviceRunStatus::Idle:
|
||||
case DeviceRunStatus::Cooling:
|
||||
if (Global::_mode != Global::Mode::Analysis) {
|
||||
Global::_mode = Global::Mode::Analysis;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
switch (cd.run_type)
|
||||
{
|
||||
case DeviceRunStatus::Heat:
|
||||
case DeviceRunStatus::ConstantTemp:
|
||||
if (Global::_mode != Global::Mode::Experiment)
|
||||
{
|
||||
Global::_mode = Global::Mode::Experiment;
|
||||
}
|
||||
break;
|
||||
case DeviceRunStatus::Idle:
|
||||
case DeviceRunStatus::Cooling:
|
||||
if (Global::_mode != Global::Mode::Analysis)
|
||||
{
|
||||
Global::_mode = Global::Mode::Analysis;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// 判断是否根据下位机数据,切换软件实验模式。
|
||||
static Global::Mode preMode = Global::Mode::Analysis;
|
||||
bool sendSaveSignalFlag = false;
|
||||
if (Global::_mode != preMode) {
|
||||
if (preMode == Global::Mode::Experiment
|
||||
&& Global::_mode == Global::Mode::Analysis) {
|
||||
static Global::Mode preMode = Global::Mode::Analysis;
|
||||
bool sendSaveSignalFlag = false;
|
||||
if (Global::_mode != preMode)
|
||||
{
|
||||
if (preMode == Global::Mode::Experiment && Global::_mode == Global::Mode::Analysis)
|
||||
{
|
||||
sendSaveSignalFlag = true;
|
||||
} else if (preMode == Global::Mode::Analysis
|
||||
&& Global::_mode == Global::Mode::Experiment) {
|
||||
}
|
||||
else if (preMode == Global::Mode::Analysis && Global::_mode == Global::Mode::Experiment)
|
||||
{
|
||||
|
||||
// 根据下位机数据,软件进入实验模式,开始实验。
|
||||
logde << "start experiment, accord to device data...";
|
||||
@ -188,8 +230,10 @@ void SerialPort::updateStatus(const CommonData &cd) {
|
||||
}
|
||||
|
||||
// If phase update, add new phase data to the global param.
|
||||
if (Global::_mode == Global::Mode::Experiment) {
|
||||
if (Global::_currentPhase != (int)cd.current_phase) {
|
||||
if (Global::_mode == Global::Mode::Experiment)
|
||||
{
|
||||
if (Global::_currentPhase != (int)cd.current_phase)
|
||||
{
|
||||
|
||||
logde << "mode experiment,phase not equeal.";
|
||||
|
||||
@ -215,31 +259,35 @@ void SerialPort::updateStatus(const CommonData &cd) {
|
||||
updateAxis();
|
||||
|
||||
// Update axis.
|
||||
bool experimentEnded = false;
|
||||
bool experimentEnded = false;
|
||||
QString devRunModeStr;
|
||||
switch (cd.run_type) {
|
||||
case DeviceRunStatus::Heat:
|
||||
devRunModeStr = "升温";
|
||||
experimentEnded = true;
|
||||
break;
|
||||
case DeviceRunStatus::ConstantTemp:
|
||||
devRunModeStr = "实验";
|
||||
experimentEnded = true;
|
||||
break;
|
||||
case DeviceRunStatus::Idle:
|
||||
case DeviceRunStatus::Cooling:
|
||||
devRunModeStr = "冷却";
|
||||
experimentEnded = false;
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
switch (cd.run_type)
|
||||
{
|
||||
case DeviceRunStatus::Heat:
|
||||
devRunModeStr = "升温";
|
||||
experimentEnded = true;
|
||||
break;
|
||||
case DeviceRunStatus::ConstantTemp:
|
||||
devRunModeStr = "实验";
|
||||
experimentEnded = true;
|
||||
break;
|
||||
case DeviceRunStatus::Idle:
|
||||
case DeviceRunStatus::Cooling:
|
||||
devRunModeStr = "冷却";
|
||||
experimentEnded = false;
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
QString msg;
|
||||
if (experimentEnded) {
|
||||
if (experimentEnded)
|
||||
{
|
||||
msg = QString("设备运行状态:%2 实验阶段:%3 实验进行中").arg(devRunModeStr).arg(cd.current_phase);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
// msg = QString("设备运行状态:%2 实验阶段:%3 实验结束").arg(devRunModeStr).arg(cd.current_phase);
|
||||
msg = QString("设备运行状态:%2 实验结束").arg(devRunModeStr);
|
||||
}
|
||||
@ -269,22 +317,30 @@ void SerialPort::updateStatus(const CommonData &cd) {
|
||||
#endif
|
||||
|
||||
// 弹出保存数据对话框。
|
||||
if (sendSaveSignalFlag && !Global::_OITAutoAnalysisModeFlag) {
|
||||
if (sendSaveSignalFlag && !Global::_OITAutoAnalysisModeFlag)
|
||||
{
|
||||
emit sigSaveExperimentalDataMsgBox();
|
||||
}
|
||||
}
|
||||
|
||||
// 解析下位机数据,更新全局参数。
|
||||
void SerialPort::commonDataParser(const int dataLength, const u16 addr,
|
||||
const CommonData &cd) {
|
||||
int localLength = dataLength;
|
||||
int localAddr = addr;
|
||||
const CommonData &cd)
|
||||
{
|
||||
|
||||
int phaseByteSize = sizeof(Phase);
|
||||
auto phaseParserFunc = [&](const int index) {
|
||||
int localLength = dataLength;
|
||||
int localAddr = addr;
|
||||
|
||||
logde << "localLength total:" << localLength;
|
||||
logde << "localAddr total:" << localAddr;
|
||||
|
||||
int phaseByteSize = sizeof(Phase);
|
||||
auto phaseParserFunc = [&](const int index)
|
||||
{
|
||||
Phase phase;
|
||||
phase.onoff = 1;
|
||||
phase.gas = cd.phase_data[index].gas;
|
||||
phase.temp_flow = cd.phase_data[index].temp_flow;
|
||||
phase.onoff = 1;
|
||||
phase.gas = cd.phase_data[index].gas;
|
||||
phase.temp_flow = cd.phase_data[index].temp_flow;
|
||||
phase.cutoff_temp = cd.phase_data[index].cutoff_temp;
|
||||
phase.constant_temp_time_min =
|
||||
cd.phase_data[index].constant_temp_time_min;
|
||||
@ -293,81 +349,103 @@ void SerialPort::commonDataParser(const int dataLength, const u16 addr,
|
||||
localAddr += phaseByteSize;
|
||||
};
|
||||
|
||||
while (localLength) {
|
||||
logde << "init_gas offset:" << offsetof(CommonData, init_gas);
|
||||
|
||||
while (localLength)
|
||||
{
|
||||
logde << "localLength:" << localLength;
|
||||
switch (localAddr) {
|
||||
case offsetof(CommonData, run_type): // 运行状态
|
||||
switch (localAddr)
|
||||
{
|
||||
case offsetof(CommonData, run_type): // 运行状态
|
||||
{
|
||||
switch (cd.run_type)
|
||||
{
|
||||
switch (cd.run_type) {
|
||||
case DeviceRunStatus::Cooling:
|
||||
// Global::instance()->setMode(Global::Mode::Analysis);
|
||||
Global::_mode = Global::Mode::Analysis;
|
||||
logde << "set global mode analysis.common data parser.";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
localAddr += 1;
|
||||
localLength -= 1;
|
||||
|
||||
break;
|
||||
}
|
||||
case offsetof(CommonData, current_gas): // 当前气氛
|
||||
// gas_type_set(dev->temp, msg_data.current_gas);
|
||||
localAddr += 1;
|
||||
localLength -= 1;
|
||||
break;
|
||||
case offsetof(CommonData, auto_pid_temp_flow): // 自整定升温速率
|
||||
localAddr += 4;
|
||||
localLength -= 4;
|
||||
break;
|
||||
case offsetof(CommonData, run_mode): {
|
||||
DeviceStartMode mode = (DeviceStartMode)cd.run_mode;
|
||||
|
||||
switch (mode) {
|
||||
case DeviceStartMode::Stop:
|
||||
Global::_mode = Global::Mode::Analysis;
|
||||
logde << "set global mode analysis.";
|
||||
break;
|
||||
case DeviceStartMode::Start:
|
||||
Global::_mode = Global::Mode::Experiment;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
//
|
||||
localLength--;
|
||||
localAddr++;
|
||||
|
||||
break;
|
||||
}
|
||||
case offsetof(CommonData, phase_data[0].onoff):
|
||||
phaseParserFunc(0);
|
||||
break;
|
||||
case offsetof(CommonData, phase_data[1].onoff):
|
||||
phaseParserFunc(1);
|
||||
break;
|
||||
case offsetof(CommonData, phase_data[2].onoff):
|
||||
phaseParserFunc(2);
|
||||
break;
|
||||
case offsetof(CommonData, phase_data[3].onoff):
|
||||
phaseParserFunc(3);
|
||||
break;
|
||||
case offsetof(CommonData, phase_data[4].onoff):
|
||||
phaseParserFunc(4);
|
||||
break;
|
||||
case offsetof(CommonData, phase_data[5].onoff):
|
||||
phaseParserFunc(5);
|
||||
case DeviceRunStatus::Cooling:
|
||||
// Global::instance()->setMode(Global::Mode::Analysis);
|
||||
Global::_mode = Global::Mode::Analysis;
|
||||
logde << "set global mode analysis.common data parser.";
|
||||
break;
|
||||
default:
|
||||
localLength--;
|
||||
break;
|
||||
}
|
||||
|
||||
localAddr += 1;
|
||||
localLength -= 1;
|
||||
|
||||
break;
|
||||
}
|
||||
case offsetof(CommonData, current_gas): // 当前气氛
|
||||
// gas_type_set(dev->temp, msg_data.current_gas);
|
||||
localAddr += 1;
|
||||
localLength -= 1;
|
||||
break;
|
||||
case offsetof(CommonData, auto_pid_temp_flow): // 自整定升温速率
|
||||
localAddr += 4;
|
||||
localLength -= 4;
|
||||
break;
|
||||
case offsetof(CommonData, run_mode):
|
||||
{
|
||||
DeviceStartMode mode = (DeviceStartMode)cd.run_mode;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case DeviceStartMode::Stop:
|
||||
Global::_mode = Global::Mode::Analysis;
|
||||
logde << "set global mode analysis.";
|
||||
break;
|
||||
case DeviceStartMode::Start:
|
||||
Global::_mode = Global::Mode::Experiment;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
//
|
||||
localLength--;
|
||||
localAddr++;
|
||||
|
||||
break;
|
||||
}
|
||||
case offsetof(CommonData, phase_data[0].onoff):
|
||||
phaseParserFunc(0);
|
||||
break;
|
||||
case offsetof(CommonData, phase_data[1].onoff):
|
||||
phaseParserFunc(1);
|
||||
break;
|
||||
case offsetof(CommonData, phase_data[2].onoff):
|
||||
phaseParserFunc(2);
|
||||
break;
|
||||
case offsetof(CommonData, phase_data[3].onoff):
|
||||
phaseParserFunc(3);
|
||||
break;
|
||||
case offsetof(CommonData, phase_data[4].onoff):
|
||||
phaseParserFunc(4);
|
||||
break;
|
||||
case offsetof(CommonData, phase_data[5].onoff):
|
||||
phaseParserFunc(5);
|
||||
break;
|
||||
// 测试类型
|
||||
case offsetof(CommonData, meas_type):
|
||||
logde << "meas_type:" << cd.meas_type;
|
||||
|
||||
localLength--;
|
||||
localAddr++;
|
||||
break;
|
||||
// 初始气氛
|
||||
case offsetof(CommonData, init_gas):
|
||||
logde << "init_gas:" << cd.init_gas;
|
||||
|
||||
localLength--;
|
||||
localAddr++;
|
||||
break;
|
||||
default:
|
||||
localLength--;
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
bool SerialPort::openSp() {
|
||||
bool SerialPort::openSp()
|
||||
{
|
||||
logde << "openSp 1";
|
||||
closeSp();
|
||||
QThread::msleep(100);
|
||||
@ -379,17 +457,20 @@ bool SerialPort::openSp() {
|
||||
#endif
|
||||
|
||||
logde << "openSp 2";
|
||||
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
|
||||
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
|
||||
{
|
||||
u16 pid = info.productIdentifier();
|
||||
u16 vid = info.vendorIdentifier();
|
||||
|
||||
if ((pid == conPid) && (vid == conVid)) {
|
||||
if ((pid == conPid) && (vid == conVid))
|
||||
{
|
||||
_sp->setPort(info);
|
||||
break;
|
||||
}
|
||||
}
|
||||
logde << "openSp 3";
|
||||
if (_sp == nullptr) {
|
||||
if (_sp == nullptr)
|
||||
{
|
||||
qDebug() << "Device not found.";
|
||||
return false;
|
||||
}
|
||||
@ -397,10 +478,10 @@ bool SerialPort::openSp() {
|
||||
// 设置波特率和读写方向
|
||||
_sp->setBaudRate(QSerialPort::Baud115200,
|
||||
QSerialPort::AllDirections);
|
||||
_sp->setDataBits(QSerialPort::Data8); // 数据位为8位
|
||||
_sp->setFlowControl(QSerialPort::NoFlowControl); // 无流控制
|
||||
_sp->setParity(QSerialPort::NoParity); // 无校验位
|
||||
_sp->setStopBits(QSerialPort::OneStop); // 一位停止位
|
||||
_sp->setDataBits(QSerialPort::Data8); // 数据位为8位
|
||||
_sp->setFlowControl(QSerialPort::NoFlowControl); // 无流控制
|
||||
_sp->setParity(QSerialPort::NoParity); // 无校验位
|
||||
_sp->setStopBits(QSerialPort::OneStop); // 一位停止位
|
||||
|
||||
// 4.连接信号槽
|
||||
connect(_sp, &QSerialPort::readyRead,
|
||||
@ -408,10 +489,13 @@ bool SerialPort::openSp() {
|
||||
|
||||
logde << "openSp 4";
|
||||
// 2.打开串口
|
||||
if (!_sp->open(QIODevice::ReadWrite)) {
|
||||
if (!_sp->open(QIODevice::ReadWrite))
|
||||
{
|
||||
qDebug() << "open failed." << _sp->error();
|
||||
return false;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
// qDebug() << "open succ.";
|
||||
logde << "openSp 5.";
|
||||
// 设置 DTR 信号为就绪状态(true 表示低电平)
|
||||
@ -422,29 +506,37 @@ bool SerialPort::openSp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SerialPort::closeSp() {
|
||||
if (_sp && _sp->isOpen()) {
|
||||
bool SerialPort::closeSp()
|
||||
{
|
||||
if (_sp && _sp->isOpen())
|
||||
{
|
||||
_sp->clear();
|
||||
_sp->close();
|
||||
}
|
||||
}
|
||||
|
||||
void SerialPort::sendCmd(const SerialPort::E_CMD_TYPE e) {
|
||||
void SerialPort::sendCmd(const SerialPort::E_CMD_TYPE e)
|
||||
{
|
||||
#if 1
|
||||
int length = 20;
|
||||
char in_char[21] = { '\0' };
|
||||
int length = 20;
|
||||
char in_char[21] = {'\0'};
|
||||
|
||||
if (e == e_zero) {
|
||||
if (e == e_zero)
|
||||
{
|
||||
// char data[10] = {'55','aa','0b','0a','20',
|
||||
// '4e','00','00','00','c3'};
|
||||
const char *data = "55aa0b0a204e000000c3";
|
||||
memcpy(in_char, data, length);
|
||||
} else if (e == e_back) {
|
||||
}
|
||||
else if (e == e_back)
|
||||
{
|
||||
// char data[10] = {'55','aa','08','10','27',
|
||||
// 'f0','d8','ff','ff','c3'};
|
||||
const char *data = "55aa081027f0d8ffffc3";
|
||||
memcpy(in_char, data, length);
|
||||
} else if (e == e_forward) {
|
||||
}
|
||||
else if (e == e_forward)
|
||||
{
|
||||
// char data[10] = {'55','aa','08','10','27',
|
||||
// '10','27','00','00','c3'};
|
||||
const char *data = "55aa08102710270000c3";
|
||||
@ -454,21 +546,26 @@ void SerialPort::sendCmd(const SerialPort::E_CMD_TYPE e) {
|
||||
#endif
|
||||
// char in_char[] = "55aa0b0a204e000000c3";
|
||||
|
||||
char out_char[21] = { '\0' };
|
||||
int hex_length = 10;
|
||||
char out_char[21] = {'\0'};
|
||||
int hex_length = 10;
|
||||
toHex(in_char, hex_length, out_char);
|
||||
|
||||
int num = _sp->write(out_char,
|
||||
hex_length);
|
||||
if (num == -1) {
|
||||
if (num == -1)
|
||||
{
|
||||
qDebug() << "write failed.";
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "write ok|num:" << num;
|
||||
}
|
||||
}
|
||||
|
||||
void SerialPort::toHex(char *in_char, int char_length, char *out_char) {
|
||||
while (char_length--) {
|
||||
void SerialPort::toHex(char *in_char, int char_length, char *out_char)
|
||||
{
|
||||
while (char_length--)
|
||||
{
|
||||
*out_char = (*in_char & 0x40 ? *in_char + 9 : *in_char) << 4;
|
||||
++in_char;
|
||||
*out_char |= (*in_char & 0x40 ? *in_char + 9 : *in_char) & 0xF;
|
||||
@ -477,12 +574,14 @@ void SerialPort::toHex(char *in_char, int char_length, char *out_char) {
|
||||
}
|
||||
}
|
||||
|
||||
void SerialPort::displayPortInfo() {
|
||||
void SerialPort::displayPortInfo()
|
||||
{
|
||||
// 获取系统中所有可用的串口信息
|
||||
QList<QSerialPortInfo> serialPorts = QSerialPortInfo::availablePorts();
|
||||
|
||||
// 遍历每个串口信息
|
||||
for (const QSerialPortInfo &portInfo : serialPorts) {
|
||||
for (const QSerialPortInfo &portInfo : serialPorts)
|
||||
{
|
||||
qDebug() << "================================================";
|
||||
// 打印串口的名称
|
||||
qDebug() << "串口名称: " << portInfo.portName();
|
||||
@ -499,14 +598,16 @@ void SerialPort::displayPortInfo() {
|
||||
// 打印是否有产品标识符
|
||||
qDebug() << "是否有产品标识符: " << (portInfo.hasProductIdentifier() ? "是" : "否");
|
||||
// 如果有虚拟调制解调器,打印其标识符
|
||||
if (portInfo.hasVendorIdentifier()) {
|
||||
if (portInfo.hasVendorIdentifier())
|
||||
{
|
||||
qint16 vid = portInfo.vendorIdentifier();
|
||||
qDebug() << "虚拟调制解调器标识符: " << vid;
|
||||
QString hexStr = QString("0x%1").arg(vid, 4, 16, QChar('0')).toUpper();
|
||||
qDebug() << "vid 0x" << hexStr;
|
||||
}
|
||||
// 如果有产品标识符,打印其标识符
|
||||
if (portInfo.hasProductIdentifier()) {
|
||||
if (portInfo.hasProductIdentifier())
|
||||
{
|
||||
qint16 pid = portInfo.productIdentifier();
|
||||
qDebug() << "产品标识符: " << pid;
|
||||
QString hexStr = QString("0x%1").arg(pid, 4, 16, QChar('0')).toUpper();
|
||||
@ -515,29 +616,34 @@ void SerialPort::displayPortInfo() {
|
||||
}
|
||||
}
|
||||
|
||||
void SerialPort::updateAxis() {
|
||||
static Global::Mode previousMode = Global::Analysis; // 记录上一次的模式
|
||||
void SerialPort::updateAxis()
|
||||
{
|
||||
static Global::Mode previousMode = Global::Analysis; // 记录上一次的模式
|
||||
|
||||
if (previousMode == Global::Analysis && Global::_mode == Global::Experiment) {
|
||||
if (previousMode == Global::Analysis && Global::_mode == Global::Experiment)
|
||||
{
|
||||
// std::cout << "Mode has changed from Analysis to Experiment!" << std::endl;
|
||||
Global::ExperimentInfo &eti = Global::_experimentInfo;
|
||||
if (eti.phaseVtr.size() > 0) {
|
||||
if (eti.phaseVtr.size() > 0)
|
||||
{
|
||||
logde << "serialport set axis.";
|
||||
float temp = eti.phaseVtr.at(0).cutoff_temp;
|
||||
emit sigAxisModify(temp);
|
||||
emit sigAxisModify(temp);
|
||||
}
|
||||
}
|
||||
|
||||
if (previousMode != Global::_mode) {
|
||||
if (previousMode != Global::_mode)
|
||||
{
|
||||
previousMode = Global::_mode;
|
||||
}
|
||||
}
|
||||
void SerialPort::parserTest() {
|
||||
const uchar data[] = { 0xa5, 0x5a, 0x2d, 0x83,
|
||||
0x00, 0x00,
|
||||
0x00, 0x01, 0x23, 0x23,
|
||||
0x23, 0x23, 0x23, 0x23, 0x23,
|
||||
0x23, 0x07, 0xbc, 0xb5, 0xf2, 0xc8, 0x57, 0x38, 0x40, 0x1b, 0x63, 0x27, 0xbc, 0x04, 0xa7, 0xf2, 0x3f, 0x55, 0x55, 0x55, 0xd5, 0x04, 0xf3, 0xab, 0xbf, 0xfa, 0x2b, 0xcd, 0x41, 0x00, 0x00, 0x93, 0xba };
|
||||
void SerialPort::parserTest()
|
||||
{
|
||||
const uchar data[] = {0xa5, 0x5a, 0x2d, 0x83,
|
||||
0x00, 0x00,
|
||||
0x00, 0x01, 0x23, 0x23,
|
||||
0x23, 0x23, 0x23, 0x23, 0x23,
|
||||
0x23, 0x07, 0xbc, 0xb5, 0xf2, 0xc8, 0x57, 0x38, 0x40, 0x1b, 0x63, 0x27, 0xbc, 0x04, 0xa7, 0xf2, 0x3f, 0x55, 0x55, 0x55, 0xd5, 0x04, 0xf3, 0xab, 0xbf, 0xfa, 0x2b, 0xcd, 0x41, 0x00, 0x00, 0x93, 0xba};
|
||||
CommonData *serialPortData = nullptr;
|
||||
|
||||
qDebug() << "data length:" << sizeof(data) / sizeof(uchar);
|
||||
@ -572,49 +678,64 @@ void SerialPort::parserTest() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void SerialPort::slotDeliverData(const QByteArray &ba) {
|
||||
void SerialPort::slotDeliverData(const QByteArray &ba)
|
||||
{
|
||||
openSp();
|
||||
slotSendData(ba);
|
||||
}
|
||||
|
||||
void SerialPort::slotSendData(const QByteArray &ba) {
|
||||
void SerialPort::slotSendData(const QByteArray &ba)
|
||||
{
|
||||
#if 1
|
||||
logde << "slotSendData ==========================";
|
||||
logde << "slotSendData:" << ba.size();
|
||||
QString hexData = ba.toHex(' '); // ' ' 作为分隔符,可选参数
|
||||
QString hexData = ba.toHex(' '); // ' ' 作为分隔符,可选参数
|
||||
logde << "slotSendData:" << hexData.toStdString();
|
||||
#endif
|
||||
|
||||
if (_sp != nullptr && _sp->isOpen()) {
|
||||
if (_sp != nullptr && _sp->isOpen())
|
||||
{
|
||||
int bytesWritten = _sp->write(ba);
|
||||
if (bytesWritten == -1) {
|
||||
if (bytesWritten == -1)
|
||||
{
|
||||
logde << "Write failed." << _sp->errorString().toStdString();
|
||||
} else if (bytesWritten != ba.size()) {
|
||||
}
|
||||
else if (bytesWritten != ba.size())
|
||||
{
|
||||
logde << "Not all data was writen.";
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
logde << "All data writen.";
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
logde << "sp not open.";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void SerialPort::slotCloseSp() {
|
||||
if (_sp != nullptr && _sp->isOpen()) {
|
||||
void SerialPort::slotCloseSp()
|
||||
{
|
||||
if (_sp != nullptr && _sp->isOpen())
|
||||
{
|
||||
_sp->close();
|
||||
}
|
||||
}
|
||||
|
||||
void SerialPort::slotPortCheck() {
|
||||
// logde<<"slotPortCheck...";
|
||||
void SerialPort::slotPortCheck()
|
||||
{
|
||||
// logde<<"slotPortCheck...";
|
||||
|
||||
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
|
||||
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
|
||||
{
|
||||
u16 pid = info.productIdentifier();
|
||||
u16 vid = info.vendorIdentifier();
|
||||
|
||||
if ((pid == conPid) && (vid == conVid)) {
|
||||
// logde<<"slotPortCheck... device connected.";
|
||||
if ((pid == conPid) && (vid == conVid))
|
||||
{
|
||||
// logde<<"slotPortCheck... device connected.";
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -622,5 +743,5 @@ void SerialPort::slotPortCheck() {
|
||||
// logde<<"device disconnected.";
|
||||
emit sigDeviceDisconnected();
|
||||
|
||||
// logde<<"slotPortCheck... device disconnected.";
|
||||
// logde<<"slotPortCheck... device disconnected.";
|
||||
}
|
||||
|
||||
@ -10,15 +10,17 @@
|
||||
#include "filemanager.h"
|
||||
#include "logger.h"
|
||||
|
||||
QString extractObjectName(const QString &fullObjectName) {
|
||||
return fullObjectName.mid(4); // 去掉前 4 个字符("ui->")
|
||||
QString extractObjectName(const QString &fullObjectName)
|
||||
{
|
||||
return fullObjectName.mid(4); // 去掉前 4 个字符("ui->")
|
||||
}
|
||||
|
||||
#define SET_OBJECT_NAME(WIDGET) \
|
||||
WIDGET->setObjectName(extractObjectName(#WIDGET))
|
||||
|
||||
ExperimentSettingForm::ExperimentSettingForm(QWidget *parent) : QWidget(parent),
|
||||
ui(new Ui::ExperimentSettingForm) {
|
||||
ui(new Ui::ExperimentSettingForm)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->sampleNameLineEdit->setText("new");
|
||||
@ -52,11 +54,13 @@ ExperimentSettingForm::ExperimentSettingForm(QWidget *parent) : QWidget(parent),
|
||||
this, &ExperimentSettingForm::slotCancel);
|
||||
}
|
||||
|
||||
ExperimentSettingForm::~ExperimentSettingForm() {
|
||||
ExperimentSettingForm::~ExperimentSettingForm()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void ExperimentSettingForm::uiReset() {
|
||||
void ExperimentSettingForm::uiReset()
|
||||
{
|
||||
// init data and status.
|
||||
|
||||
// default value
|
||||
@ -164,84 +168,90 @@ void ExperimentSettingForm::uiReset() {
|
||||
SET_OBJECT_NAME(ui->comboBox_initial_atmosphere);
|
||||
}
|
||||
|
||||
void ExperimentSettingForm::uiSetPhaseEnable(const int index) {
|
||||
switch (index) {
|
||||
case 1:
|
||||
ui->checkBox_phase_1->setTristate(true);
|
||||
ui->phase_1_cutoff_temp->setEnabled(true);
|
||||
ui->phase_1_scan_rate->setEnabled(true);
|
||||
ui->phase_1_constant_temp->setEnabled(true);
|
||||
ui->comboBox_phase_1_atmosphere->setEnabled(true);
|
||||
break;
|
||||
case 2:
|
||||
ui->checkBox_phase_2->setTristate(true);
|
||||
ui->phase_2_cutoff_temp->setEnabled(true);
|
||||
ui->phase_2_scan_rate->setEnabled(true);
|
||||
ui->phase_3_constant_temp->setEnabled(true);
|
||||
ui->comboBox_phase_1_atmosphere->setEnabled(true);
|
||||
break;
|
||||
case 3:
|
||||
ui->checkBox_phase_1->setTristate(true);
|
||||
ui->phase_1_cutoff_temp->setEnabled(true);
|
||||
ui->phase_1_scan_rate->setEnabled(true);
|
||||
ui->phase_1_constant_temp->setEnabled(true);
|
||||
ui->comboBox_phase_1_atmosphere->setEnabled(true);
|
||||
break;
|
||||
case 4:
|
||||
ui->checkBox_phase_1->setTristate(true);
|
||||
ui->phase_1_cutoff_temp->setEnabled(true);
|
||||
ui->phase_1_scan_rate->setEnabled(true);
|
||||
ui->phase_1_constant_temp->setEnabled(true);
|
||||
ui->comboBox_phase_1_atmosphere->setEnabled(true);
|
||||
break;
|
||||
case 5:
|
||||
ui->checkBox_phase_1->setTristate(true);
|
||||
ui->phase_1_cutoff_temp->setEnabled(true);
|
||||
ui->phase_1_scan_rate->setEnabled(true);
|
||||
ui->phase_1_constant_temp->setEnabled(true);
|
||||
ui->comboBox_phase_1_atmosphere->setEnabled(true);
|
||||
break;
|
||||
case 6:
|
||||
ui->checkBox_phase_1->setTristate(true);
|
||||
ui->phase_1_cutoff_temp->setEnabled(true);
|
||||
ui->phase_1_scan_rate->setEnabled(true);
|
||||
ui->phase_1_constant_temp->setEnabled(true);
|
||||
ui->comboBox_phase_1_atmosphere->setEnabled(true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
void ExperimentSettingForm::uiSetPhaseEnable(const int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 1:
|
||||
ui->checkBox_phase_1->setTristate(true);
|
||||
ui->phase_1_cutoff_temp->setEnabled(true);
|
||||
ui->phase_1_scan_rate->setEnabled(true);
|
||||
ui->phase_1_constant_temp->setEnabled(true);
|
||||
ui->comboBox_phase_1_atmosphere->setEnabled(true);
|
||||
break;
|
||||
case 2:
|
||||
ui->checkBox_phase_2->setTristate(true);
|
||||
ui->phase_2_cutoff_temp->setEnabled(true);
|
||||
ui->phase_2_scan_rate->setEnabled(true);
|
||||
ui->phase_3_constant_temp->setEnabled(true);
|
||||
ui->comboBox_phase_1_atmosphere->setEnabled(true);
|
||||
break;
|
||||
case 3:
|
||||
ui->checkBox_phase_1->setTristate(true);
|
||||
ui->phase_1_cutoff_temp->setEnabled(true);
|
||||
ui->phase_1_scan_rate->setEnabled(true);
|
||||
ui->phase_1_constant_temp->setEnabled(true);
|
||||
ui->comboBox_phase_1_atmosphere->setEnabled(true);
|
||||
break;
|
||||
case 4:
|
||||
ui->checkBox_phase_1->setTristate(true);
|
||||
ui->phase_1_cutoff_temp->setEnabled(true);
|
||||
ui->phase_1_scan_rate->setEnabled(true);
|
||||
ui->phase_1_constant_temp->setEnabled(true);
|
||||
ui->comboBox_phase_1_atmosphere->setEnabled(true);
|
||||
break;
|
||||
case 5:
|
||||
ui->checkBox_phase_1->setTristate(true);
|
||||
ui->phase_1_cutoff_temp->setEnabled(true);
|
||||
ui->phase_1_scan_rate->setEnabled(true);
|
||||
ui->phase_1_constant_temp->setEnabled(true);
|
||||
ui->comboBox_phase_1_atmosphere->setEnabled(true);
|
||||
break;
|
||||
case 6:
|
||||
ui->checkBox_phase_1->setTristate(true);
|
||||
ui->phase_1_cutoff_temp->setEnabled(true);
|
||||
ui->phase_1_scan_rate->setEnabled(true);
|
||||
ui->phase_1_constant_temp->setEnabled(true);
|
||||
ui->comboBox_phase_1_atmosphere->setEnabled(true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GasType ExperimentSettingForm::conver2GasType(const int index) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return GasType::NC;
|
||||
break; // 假设 GAS_AIR 是 gas_type 的枚举值
|
||||
case 1:
|
||||
return GasType::N2;
|
||||
break;
|
||||
case 2:
|
||||
return GasType::O2;
|
||||
break;
|
||||
default:
|
||||
return GasType::NC;
|
||||
break; // 处理未知情况
|
||||
GasType ExperimentSettingForm::conver2GasType(const int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return GasType::NC;
|
||||
break; // 假设 GAS_AIR 是 gas_type 的枚举值
|
||||
case 1:
|
||||
return GasType::N2;
|
||||
break;
|
||||
case 2:
|
||||
return GasType::O2;
|
||||
break;
|
||||
default:
|
||||
return GasType::NC;
|
||||
break; // 处理未知情况
|
||||
}
|
||||
return GasType::NC;
|
||||
}
|
||||
|
||||
bool ExperimentSettingForm::phaseCufoffTempAndTempFlowCheck(const int phaseIndex,
|
||||
bool ExperimentSettingForm::phaseCufoffTempAndTempFlowCheck(const int phaseIndex,
|
||||
const float prePhaseCufoffTemp,
|
||||
const float currentPhaseCufoffTemp,
|
||||
const float tempFlow) {
|
||||
if (tempFlow < 0) {
|
||||
const float tempFlow)
|
||||
{
|
||||
if (tempFlow < 0)
|
||||
{
|
||||
phaseScanRateErrorMesgBox(phaseIndex);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (prePhaseCufoffTemp != currentPhaseCufoffTemp
|
||||
&& tempFlow == 0) {
|
||||
if (prePhaseCufoffTemp != currentPhaseCufoffTemp && tempFlow == 0)
|
||||
{
|
||||
phaseScanRateErrorMesgBox(phaseIndex);
|
||||
return false;
|
||||
}
|
||||
@ -249,19 +259,26 @@ bool ExperimentSettingForm::phaseCufoffTempAndTempFlowCheck(const int phaseInd
|
||||
return true;
|
||||
}
|
||||
|
||||
void ExperimentSettingForm::slotPhase2StateChanged(int state) {
|
||||
void ExperimentSettingForm::slotPhase2StateChanged(int state)
|
||||
{
|
||||
qDebug() << "slotPhase2StateChanged:" << state;
|
||||
|
||||
if (state == Qt::PartiallyChecked) {
|
||||
if (state == Qt::PartiallyChecked)
|
||||
{
|
||||
ui->phase_2_cutoff_temp->setEnabled(true);
|
||||
ui->phase_2_scan_rate->setEnabled(true);
|
||||
ui->phase_2_constant_temp->setEnabled(true);
|
||||
ui->comboBox_phase_2_atmosphere->setEnabled(true);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
// unchecked
|
||||
if (ui->checkBox_phase_3->isChecked()) {
|
||||
if (ui->checkBox_phase_3->isChecked())
|
||||
{
|
||||
ui->checkBox_phase_2->setChecked(true);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->phase_2_cutoff_temp->setEnabled(false);
|
||||
ui->phase_2_scan_rate->setEnabled(false);
|
||||
ui->phase_2_constant_temp->setEnabled(false);
|
||||
@ -270,20 +287,30 @@ void ExperimentSettingForm::slotPhase2StateChanged(int state) {
|
||||
}
|
||||
}
|
||||
|
||||
void ExperimentSettingForm::slotPhase3StateChanged(int state) {
|
||||
if (state == Qt::PartiallyChecked) {
|
||||
if (ui->checkBox_phase_2->isChecked()) {
|
||||
void ExperimentSettingForm::slotPhase3StateChanged(int state)
|
||||
{
|
||||
if (state == Qt::PartiallyChecked)
|
||||
{
|
||||
if (ui->checkBox_phase_2->isChecked())
|
||||
{
|
||||
ui->phase_3_cutoff_temp->setEnabled(true);
|
||||
ui->phase_3_scan_rate->setEnabled(true);
|
||||
ui->phase_3_constant_temp->setEnabled(true);
|
||||
ui->comboBox_phase_3_atmosphere->setEnabled(true);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->checkBox_phase_3->setChecked(false);
|
||||
}
|
||||
} else {
|
||||
if (ui->checkBox_phase_4->isChecked()) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ui->checkBox_phase_4->isChecked())
|
||||
{
|
||||
ui->checkBox_phase_3->setChecked(true);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->phase_3_cutoff_temp->setEnabled(false);
|
||||
ui->phase_3_scan_rate->setEnabled(false);
|
||||
ui->phase_3_constant_temp->setEnabled(false);
|
||||
@ -292,20 +319,30 @@ void ExperimentSettingForm::slotPhase3StateChanged(int state) {
|
||||
}
|
||||
}
|
||||
|
||||
void ExperimentSettingForm::slotPhase4StateChanged(int state) {
|
||||
if (state == Qt::PartiallyChecked) {
|
||||
if (ui->checkBox_phase_3->isChecked()) {
|
||||
void ExperimentSettingForm::slotPhase4StateChanged(int state)
|
||||
{
|
||||
if (state == Qt::PartiallyChecked)
|
||||
{
|
||||
if (ui->checkBox_phase_3->isChecked())
|
||||
{
|
||||
ui->phase_4_cutoff_temp->setEnabled(true);
|
||||
ui->phase_4_scan_rate->setEnabled(true);
|
||||
ui->phase_4_constant_temp->setEnabled(true);
|
||||
ui->comboBox_phase_4_atmosphere->setEnabled(true);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->checkBox_phase_4->setChecked(false);
|
||||
}
|
||||
} else {
|
||||
if (ui->checkBox_phase_5->isChecked()) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ui->checkBox_phase_5->isChecked())
|
||||
{
|
||||
ui->checkBox_phase_4->setChecked(true);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->phase_4_cutoff_temp->setEnabled(false);
|
||||
ui->phase_4_scan_rate->setEnabled(false);
|
||||
ui->phase_4_constant_temp->setEnabled(false);
|
||||
@ -314,20 +351,30 @@ void ExperimentSettingForm::slotPhase4StateChanged(int state) {
|
||||
}
|
||||
}
|
||||
|
||||
void ExperimentSettingForm::slotPhase5StateChanged(int state) {
|
||||
if (state == Qt::PartiallyChecked) {
|
||||
if (ui->checkBox_phase_4->isChecked()) {
|
||||
void ExperimentSettingForm::slotPhase5StateChanged(int state)
|
||||
{
|
||||
if (state == Qt::PartiallyChecked)
|
||||
{
|
||||
if (ui->checkBox_phase_4->isChecked())
|
||||
{
|
||||
ui->phase_5_cutoff_temp->setEnabled(true);
|
||||
ui->phase_5_scan_rate->setEnabled(true);
|
||||
ui->phase_5_constant_temp->setEnabled(true);
|
||||
ui->comboBox_phase_5_atmosphere->setEnabled(true);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->checkBox_phase_5->setChecked(false);
|
||||
}
|
||||
} else {
|
||||
if (ui->checkBox_phase_6->isChecked()) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ui->checkBox_phase_6->isChecked())
|
||||
{
|
||||
ui->checkBox_phase_5->setChecked(true);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->phase_5_cutoff_temp->setEnabled(false);
|
||||
ui->phase_5_scan_rate->setEnabled(false);
|
||||
ui->phase_5_constant_temp->setEnabled(false);
|
||||
@ -336,27 +383,35 @@ void ExperimentSettingForm::slotPhase5StateChanged(int state) {
|
||||
}
|
||||
}
|
||||
|
||||
void ExperimentSettingForm::slotPhase6StateChanged(int state) {
|
||||
void ExperimentSettingForm::slotPhase6StateChanged(int state)
|
||||
{
|
||||
qDebug() << "slotPhase2StateChanged:" << state;
|
||||
|
||||
if (state == Qt::PartiallyChecked) {
|
||||
if (ui->checkBox_phase_5->isChecked()) {
|
||||
if (state == Qt::PartiallyChecked)
|
||||
{
|
||||
if (ui->checkBox_phase_5->isChecked())
|
||||
{
|
||||
ui->phase_6_cutoff_temp->setEnabled(true);
|
||||
ui->phase_6_scan_rate->setEnabled(true);
|
||||
ui->phase_6_constant_temp->setEnabled(true);
|
||||
ui->comboBox_phase_6_atmosphere->setEnabled(true);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->checkBox_phase_6->setChecked(false);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->phase_6_cutoff_temp->setEnabled(false);
|
||||
ui->phase_6_scan_rate->setEnabled(false);
|
||||
ui->phase_6_constant_temp->setEnabled(false);
|
||||
ui->comboBox_phase_6_atmosphere->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
|
||||
// 发布数据
|
||||
void ExperimentSettingForm::on_pushButton_deliverData_clicked()
|
||||
{
|
||||
float phase1CutoffTemp = 0.0;
|
||||
float phase2CutoffTemp = 0.0;
|
||||
float phase3CutoffTemp = 0.0;
|
||||
@ -367,9 +422,9 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
|
||||
QVector<Phase> phaseVtr;
|
||||
{
|
||||
Phase phase;
|
||||
phase.onoff = ui->checkBox_phase_1->checkState() ? 1 : 0;
|
||||
phase.cutoff_temp = ui->phase_1_cutoff_temp->text().toFloat();
|
||||
phase.temp_flow = ui->phase_1_scan_rate->text().toFloat();
|
||||
phase.onoff = ui->checkBox_phase_1->checkState() ? 1 : 0;
|
||||
phase.cutoff_temp = ui->phase_1_cutoff_temp->text().toFloat();
|
||||
phase.temp_flow = ui->phase_1_scan_rate->text().toFloat();
|
||||
phase.constant_temp_time_min = (uint16_t)ui->phase_1_constant_temp->text().toInt();
|
||||
|
||||
phase.gas = conver2GasType(ui->comboBox_phase_1_atmosphere->currentIndex());
|
||||
@ -378,7 +433,8 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
|
||||
//
|
||||
phase1CutoffTemp = phase.cutoff_temp;
|
||||
//
|
||||
if (phase.temp_flow <= 0) {
|
||||
if (phase.temp_flow <= 0)
|
||||
{
|
||||
phaseScanRateErrorMesgBox(1);
|
||||
return;
|
||||
}
|
||||
@ -386,18 +442,20 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
|
||||
|
||||
{
|
||||
Phase phase;
|
||||
phase.onoff = ui->checkBox_phase_2->checkState() ? 1 : 0;
|
||||
phase.cutoff_temp = ui->phase_2_cutoff_temp->text().toFloat();
|
||||
phase.temp_flow = ui->phase_2_scan_rate->text().toFloat();
|
||||
phase.onoff = ui->checkBox_phase_2->checkState() ? 1 : 0;
|
||||
phase.cutoff_temp = ui->phase_2_cutoff_temp->text().toFloat();
|
||||
phase.temp_flow = ui->phase_2_scan_rate->text().toFloat();
|
||||
phase.constant_temp_time_min = (uint16_t)ui->phase_2_constant_temp->text().toInt();
|
||||
phase.gas = conver2GasType(ui->comboBox_phase_2_atmosphere->currentIndex());
|
||||
phase.gas = conver2GasType(ui->comboBox_phase_2_atmosphere->currentIndex());
|
||||
|
||||
phaseVtr.push_back(phase);
|
||||
//
|
||||
if (phase.onoff) {
|
||||
if (phase.onoff)
|
||||
{
|
||||
logde << "phase 2 enable.";
|
||||
phase2CutoffTemp = phase.cutoff_temp;
|
||||
if (phase2CutoffTemp < phase1CutoffTemp) {
|
||||
if (phase2CutoffTemp < phase1CutoffTemp)
|
||||
{
|
||||
phaseCufoffTempErrorMesgBox(2);
|
||||
return;
|
||||
}
|
||||
@ -418,7 +476,8 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
|
||||
if (!phaseCufoffTempAndTempFlowCheck(2,
|
||||
phase1CutoffTemp,
|
||||
phase2CutoffTemp,
|
||||
phase.temp_flow)) {
|
||||
phase.temp_flow))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -426,18 +485,20 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
|
||||
|
||||
{
|
||||
Phase phase;
|
||||
phase.onoff = ui->checkBox_phase_3->checkState() ? 1 : 0;
|
||||
phase.cutoff_temp = ui->phase_3_cutoff_temp->text().toFloat();
|
||||
phase.temp_flow = ui->phase_3_scan_rate->text().toFloat();
|
||||
phase.onoff = ui->checkBox_phase_3->checkState() ? 1 : 0;
|
||||
phase.cutoff_temp = ui->phase_3_cutoff_temp->text().toFloat();
|
||||
phase.temp_flow = ui->phase_3_scan_rate->text().toFloat();
|
||||
phase.constant_temp_time_min = (uint16_t)ui->phase_3_constant_temp->text().toInt();
|
||||
phase.gas = conver2GasType(ui->comboBox_phase_3_atmosphere->currentIndex());
|
||||
phase.gas = conver2GasType(ui->comboBox_phase_3_atmosphere->currentIndex());
|
||||
|
||||
phaseVtr.push_back(phase);
|
||||
//
|
||||
if (phase.onoff) {
|
||||
if (phase.onoff)
|
||||
{
|
||||
logde << "phase 3 enable.";
|
||||
phase3CutoffTemp = phase.cutoff_temp;
|
||||
if (phase3CutoffTemp < phase2CutoffTemp) {
|
||||
if (phase3CutoffTemp < phase2CutoffTemp)
|
||||
{
|
||||
phaseCufoffTempErrorMesgBox(3);
|
||||
return;
|
||||
}
|
||||
@ -450,7 +511,8 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
|
||||
if (!phaseCufoffTempAndTempFlowCheck(3,
|
||||
phase2CutoffTemp,
|
||||
phase3CutoffTemp,
|
||||
phase.temp_flow)) {
|
||||
phase.temp_flow))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -458,18 +520,20 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
|
||||
|
||||
{
|
||||
Phase phase;
|
||||
phase.onoff = ui->checkBox_phase_4->checkState() ? 1 : 0;
|
||||
phase.cutoff_temp = ui->phase_4_cutoff_temp->text().toFloat();
|
||||
phase.temp_flow = ui->phase_4_scan_rate->text().toFloat();
|
||||
phase.onoff = ui->checkBox_phase_4->checkState() ? 1 : 0;
|
||||
phase.cutoff_temp = ui->phase_4_cutoff_temp->text().toFloat();
|
||||
phase.temp_flow = ui->phase_4_scan_rate->text().toFloat();
|
||||
phase.constant_temp_time_min = (uint16_t)ui->phase_4_constant_temp->text().toInt();
|
||||
phase.gas = conver2GasType(ui->comboBox_phase_4_atmosphere->currentIndex());
|
||||
phase.gas = conver2GasType(ui->comboBox_phase_4_atmosphere->currentIndex());
|
||||
|
||||
phaseVtr.push_back(phase);
|
||||
//
|
||||
if (phase.onoff) {
|
||||
if (phase.onoff)
|
||||
{
|
||||
logde << "phase 4 enable.";
|
||||
phase4CutoffTemp = phase.cutoff_temp;
|
||||
if (phase4CutoffTemp < phase3CutoffTemp) {
|
||||
if (phase4CutoffTemp < phase3CutoffTemp)
|
||||
{
|
||||
phaseCufoffTempErrorMesgBox(4);
|
||||
return;
|
||||
}
|
||||
@ -482,7 +546,8 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
|
||||
if (!phaseCufoffTempAndTempFlowCheck(4,
|
||||
phase3CutoffTemp,
|
||||
phase4CutoffTemp,
|
||||
phase.temp_flow)) {
|
||||
phase.temp_flow))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -490,18 +555,20 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
|
||||
|
||||
{
|
||||
Phase phase;
|
||||
phase.onoff = ui->checkBox_phase_5->checkState() ? 1 : 0;
|
||||
phase.cutoff_temp = ui->phase_5_cutoff_temp->text().toFloat();
|
||||
phase.temp_flow = ui->phase_5_scan_rate->text().toFloat();
|
||||
phase.onoff = ui->checkBox_phase_5->checkState() ? 1 : 0;
|
||||
phase.cutoff_temp = ui->phase_5_cutoff_temp->text().toFloat();
|
||||
phase.temp_flow = ui->phase_5_scan_rate->text().toFloat();
|
||||
phase.constant_temp_time_min = (uint16_t)ui->phase_5_constant_temp->text().toInt();
|
||||
phase.gas = conver2GasType(ui->comboBox_phase_5_atmosphere->currentIndex());
|
||||
phase.gas = conver2GasType(ui->comboBox_phase_5_atmosphere->currentIndex());
|
||||
|
||||
phaseVtr.push_back(phase);
|
||||
//
|
||||
if (phase.onoff) {
|
||||
if (phase.onoff)
|
||||
{
|
||||
logde << "phase 5 enable.";
|
||||
phase5CutoffTemp = phase.cutoff_temp;
|
||||
if (phase5CutoffTemp < phase4CutoffTemp) {
|
||||
if (phase5CutoffTemp < phase4CutoffTemp)
|
||||
{
|
||||
phaseCufoffTempErrorMesgBox(5);
|
||||
return;
|
||||
}
|
||||
@ -514,7 +581,8 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
|
||||
if (!phaseCufoffTempAndTempFlowCheck(5,
|
||||
phase4CutoffTemp,
|
||||
phase5CutoffTemp,
|
||||
phase.temp_flow)) {
|
||||
phase.temp_flow))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -522,18 +590,20 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
|
||||
|
||||
{
|
||||
Phase phase;
|
||||
phase.onoff = ui->checkBox_phase_6->checkState() ? 1 : 0;
|
||||
phase.cutoff_temp = ui->phase_6_cutoff_temp->text().toFloat();
|
||||
phase.temp_flow = ui->phase_6_scan_rate->text().toFloat();
|
||||
phase.onoff = ui->checkBox_phase_6->checkState() ? 1 : 0;
|
||||
phase.cutoff_temp = ui->phase_6_cutoff_temp->text().toFloat();
|
||||
phase.temp_flow = ui->phase_6_scan_rate->text().toFloat();
|
||||
phase.constant_temp_time_min = (uint16_t)ui->phase_6_constant_temp->text().toInt();
|
||||
phase.gas = conver2GasType(ui->comboBox_phase_6_atmosphere->currentIndex());
|
||||
phase.gas = conver2GasType(ui->comboBox_phase_6_atmosphere->currentIndex());
|
||||
|
||||
phaseVtr.push_back(phase);
|
||||
//
|
||||
if (phase.onoff) {
|
||||
if (phase.onoff)
|
||||
{
|
||||
logde << "phase 6 enable.";
|
||||
phase6CutoffTemp = phase.cutoff_temp;
|
||||
if (phase6CutoffTemp < phase5CutoffTemp) {
|
||||
if (phase6CutoffTemp < phase5CutoffTemp)
|
||||
{
|
||||
phaseCufoffTempErrorMesgBox(6);
|
||||
return;
|
||||
}
|
||||
@ -546,17 +616,18 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
|
||||
if (!phaseCufoffTempAndTempFlowCheck(6,
|
||||
phase5CutoffTemp,
|
||||
phase6CutoffTemp,
|
||||
phase.temp_flow)) {
|
||||
phase.temp_flow))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
Global::ExperimentInfo &ei = Global::_experimentInfo;
|
||||
ei.sampleName = ui->sampleNameLineEdit->text();
|
||||
ei.sampleWeight = ui->sampleWeightLineEdit->text();
|
||||
ei.date = ui->dateTimeLineEdit->text();
|
||||
ei.experimentor = ui->userLineEdit->text();
|
||||
ei.sampleName = ui->sampleNameLineEdit->text();
|
||||
ei.sampleWeight = ui->sampleWeightLineEdit->text();
|
||||
ei.date = ui->dateTimeLineEdit->text();
|
||||
ei.experimentor = ui->userLineEdit->text();
|
||||
|
||||
#if 0
|
||||
ei.phaseVtr = phaseVtr;
|
||||
@ -571,13 +642,16 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
|
||||
|
||||
// initial data.
|
||||
QByteArray initialBa;
|
||||
if (ui->radioButton_OIT->isChecked()) {
|
||||
if (ui->radioButton_OIT->isChecked())
|
||||
{
|
||||
initialBa.append((char)0);
|
||||
|
||||
Global::_experimentOITFlag = true;
|
||||
|
||||
logde << "Global::_experimentOITFlag = true;";
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
initialBa.append((char)1);
|
||||
|
||||
Global::_experimentOITFlag = false;
|
||||
@ -589,7 +663,8 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
|
||||
initialBa.append(index);
|
||||
|
||||
// 实验名称检查
|
||||
if (Global::isFileExist(ei.sampleName)) {
|
||||
if (Global::isFileExist(ei.sampleName))
|
||||
{
|
||||
QMessageBox::question(this, "实验名称重复", "实验名称已存在,请重新输入!",
|
||||
QMessageBox::Yes);
|
||||
return;
|
||||
@ -603,55 +678,73 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
|
||||
hide();
|
||||
}
|
||||
|
||||
void ExperimentSettingForm::slotCancel() {
|
||||
void ExperimentSettingForm::slotCancel()
|
||||
{
|
||||
hide();
|
||||
}
|
||||
|
||||
void ExperimentSettingForm::phaseCufoffTempErrorMesgBox(const int phaseNum) {
|
||||
void ExperimentSettingForm::phaseCufoffTempErrorMesgBox(const int phaseNum)
|
||||
{
|
||||
QString title = QString("阶段%1截止温度错误").arg(QString::number(phaseNum));
|
||||
QString text = QString("阶段%1截止温度不能小于上一阶段截止温度! ").arg(QString::number(phaseNum));
|
||||
QString text = QString("阶段%1截止温度不能小于上一阶段截止温度! ").arg(QString::number(phaseNum));
|
||||
QMessageBox::question(this, title, text,
|
||||
QMessageBox::Yes);
|
||||
}
|
||||
|
||||
void ExperimentSettingForm::phaseScanRateErrorMesgBox(const int phaseNum) {
|
||||
void ExperimentSettingForm::phaseScanRateErrorMesgBox(const int phaseNum)
|
||||
{
|
||||
QString title = QString("阶段%1扫描速率错误").arg(QString::number(phaseNum));
|
||||
QString text = QString("阶段%1扫描速率必须大于0! ").arg(QString::number(phaseNum));
|
||||
QString text = QString("阶段%1扫描速率必须大于0! ").arg(QString::number(phaseNum));
|
||||
QMessageBox::question(this, title, text,
|
||||
QMessageBox::Yes);
|
||||
}
|
||||
void ExperimentSettingForm::slotPhaseCheck() {
|
||||
if (sender() == ui->checkBox_phase_2) {
|
||||
if (ui->checkBox_phase_2->isChecked()) {
|
||||
void ExperimentSettingForm::slotPhaseCheck()
|
||||
{
|
||||
if (sender() == ui->checkBox_phase_2)
|
||||
{
|
||||
if (ui->checkBox_phase_2->isChecked())
|
||||
{
|
||||
ui->phase_2_cutoff_temp->setEnabled(true);
|
||||
ui->phase_2_scan_rate->setEnabled(true);
|
||||
ui->phase_2_constant_temp->setEnabled(true);
|
||||
ui->comboBox_phase_2_atmosphere->setEnabled(true);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->phase_2_cutoff_temp->setEnabled(false);
|
||||
ui->phase_2_scan_rate->setEnabled(false);
|
||||
ui->phase_2_constant_temp->setEnabled(false);
|
||||
ui->comboBox_phase_2_atmosphere->setEnabled(false);
|
||||
}
|
||||
} else if (sender() == ui->checkBox_phase_3) {
|
||||
if (ui->checkBox_phase_3->isChecked()) {
|
||||
}
|
||||
else if (sender() == ui->checkBox_phase_3)
|
||||
{
|
||||
if (ui->checkBox_phase_3->isChecked())
|
||||
{
|
||||
ui->phase_3_cutoff_temp->setEnabled(true);
|
||||
ui->phase_3_scan_rate->setEnabled(true);
|
||||
ui->phase_3_constant_temp->setEnabled(true);
|
||||
ui->comboBox_phase_3_atmosphere->setEnabled(true);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->phase_3_cutoff_temp->setEnabled(false);
|
||||
ui->phase_3_scan_rate->setEnabled(false);
|
||||
ui->phase_3_constant_temp->setEnabled(false);
|
||||
ui->comboBox_phase_3_atmosphere->setEnabled(false);
|
||||
}
|
||||
} else if (sender() == ui->checkBox_phase_4) {
|
||||
if (ui->checkBox_phase_4->isChecked()) {
|
||||
}
|
||||
else if (sender() == ui->checkBox_phase_4)
|
||||
{
|
||||
if (ui->checkBox_phase_4->isChecked())
|
||||
{
|
||||
ui->phase_4_cutoff_temp->setEnabled(true);
|
||||
ui->phase_4_scan_rate->setEnabled(true);
|
||||
ui->phase_4_constant_temp->setEnabled(true);
|
||||
ui->comboBox_phase_4_atmosphere->setEnabled(true);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->phase_4_cutoff_temp->setEnabled(false);
|
||||
ui->phase_4_scan_rate->setEnabled(false);
|
||||
ui->phase_4_constant_temp->setEnabled(false);
|
||||
@ -660,23 +753,25 @@ void ExperimentSettingForm::slotPhaseCheck() {
|
||||
}
|
||||
}
|
||||
|
||||
void ExperimentSettingForm::slotRecvPhaseInfo(const QByteArray &ba) {
|
||||
void ExperimentSettingForm::slotRecvPhaseInfo(const QByteArray &ba)
|
||||
{
|
||||
logde << "recv phase info ----------------------- ";
|
||||
|
||||
#if 1
|
||||
QString hexData = ba.toHex(' '); // ' ' 作为分隔符,可选参数
|
||||
QString hexData = ba.toHex(' '); // ' ' 作为分隔符,可选参数
|
||||
qDebug() << "slotRecvPhaseInfo hex:" << hexData;
|
||||
#endif
|
||||
|
||||
QByteArray localba = ba;
|
||||
SerialPortProtocol *spp = (SerialPortProtocol *)localba.data();
|
||||
QByteArray localba = ba;
|
||||
SerialPortProtocol *spp = (SerialPortProtocol *)localba.data();
|
||||
|
||||
u8 *data = spp->data_buf;
|
||||
|
||||
int phaseSize = spp->len / PHASE_BYTE_SIZE;
|
||||
|
||||
QVector<Phase> phaseVtr;
|
||||
for (int i = 0; i < phaseSize; i++) {
|
||||
for (int i = 0; i < phaseSize; i++)
|
||||
{
|
||||
#if 0
|
||||
Phase *phase = (Phase *)(data + i * PHASE_BYTE_SIZE);
|
||||
phaseVtr.push_back(*phase);
|
||||
@ -719,7 +814,7 @@ void ExperimentSettingForm::slotRecvPhaseInfo(const QByteArray &ba) {
|
||||
phaseVtr.push_back(phase);
|
||||
#endif
|
||||
uint8_t *localData = data + i * PHASE_BYTE_SIZE;
|
||||
int index = 0;
|
||||
int index = 0;
|
||||
|
||||
Phase phase;
|
||||
// 解析 onoff
|
||||
@ -741,19 +836,20 @@ void ExperimentSettingForm::slotRecvPhaseInfo(const QByteArray &ba) {
|
||||
|
||||
// 解析 gas
|
||||
uint8_t gasType = *(localData + index);
|
||||
switch (gasType) {
|
||||
case NC:
|
||||
phase.gas = NC;
|
||||
break;
|
||||
case N2:
|
||||
phase.gas = N2;
|
||||
break;
|
||||
case O2:
|
||||
phase.gas = O2;
|
||||
break;
|
||||
default:
|
||||
phase.gas = NC; // 默认值,表示未知类型
|
||||
break;
|
||||
switch (gasType)
|
||||
{
|
||||
case NC:
|
||||
phase.gas = NC;
|
||||
break;
|
||||
case N2:
|
||||
phase.gas = N2;
|
||||
break;
|
||||
case O2:
|
||||
phase.gas = O2;
|
||||
break;
|
||||
default:
|
||||
phase.gas = NC; // 默认值,表示未知类型
|
||||
break;
|
||||
}
|
||||
phaseVtr.push_back(phase);
|
||||
}
|
||||
@ -763,51 +859,62 @@ void ExperimentSettingForm::slotRecvPhaseInfo(const QByteArray &ba) {
|
||||
// ui update
|
||||
// logde<<"phaseVtr size:"<<phaseVtr.size();
|
||||
|
||||
// ui重置成默认状态
|
||||
uiReset();
|
||||
|
||||
for (int i = 0; i < phaseVtr.size();) {
|
||||
// ui设置实验阶段参数
|
||||
for (int i = 0; i < phaseVtr.size();)
|
||||
{
|
||||
const Phase &phase = phaseVtr[i];
|
||||
if (phase.onoff == 0) {
|
||||
if (phase.onoff == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
i++;
|
||||
// qDebug()<<"index :"<<i;
|
||||
|
||||
QString checkBoxName = QString("checkBox_phase_%1").arg(i);
|
||||
QString checkBoxName = QString("checkBox_phase_%1").arg(i);
|
||||
QCheckBox *checkBox_phase = qobject_cast<QCheckBox *>(this->findChild<QObject *>(checkBoxName));
|
||||
if (checkBox_phase) {
|
||||
if (checkBox_phase)
|
||||
{
|
||||
checkBox_phase->setChecked(true);
|
||||
// qDebug()<<"found...";
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
// qDebug()<<"not found...";
|
||||
}
|
||||
|
||||
QString cutOffTempLineEditName = QString("phase_%1_cutoff_temp").arg(i);
|
||||
QLineEdit *cutOffTempLineEdit = qobject_cast<QLineEdit *>(this->findChild<QObject *>(cutOffTempLineEditName));
|
||||
if (cutOffTempLineEdit) {
|
||||
QString cutOffTempLineEditName = QString("phase_%1_cutoff_temp").arg(i);
|
||||
QLineEdit *cutOffTempLineEdit = qobject_cast<QLineEdit *>(this->findChild<QObject *>(cutOffTempLineEditName));
|
||||
if (cutOffTempLineEdit)
|
||||
{
|
||||
cutOffTempLineEdit->setText(QString::number(phase.cutoff_temp, 'f', 3));
|
||||
cutOffTempLineEdit->setEnabled(true);
|
||||
}
|
||||
|
||||
QString scanRateLineEditName = QString("phase_%1_scan_rate").arg(i);
|
||||
QString scanRateLineEditName = QString("phase_%1_scan_rate").arg(i);
|
||||
QLineEdit *scanRateLineEdit =
|
||||
qobject_cast<QLineEdit *>(this->findChild<QObject *>(scanRateLineEditName));
|
||||
if (scanRateLineEdit) {
|
||||
if (scanRateLineEdit)
|
||||
{
|
||||
scanRateLineEdit->setText(QString::number(phase.temp_flow, 'f', 3));
|
||||
scanRateLineEdit->setEnabled(true);
|
||||
}
|
||||
QString constantTempLineEditName = QString("phase_%1_constant_temp").arg(i);
|
||||
QString constantTempLineEditName = QString("phase_%1_constant_temp").arg(i);
|
||||
QLineEdit *constantTempLineEdit =
|
||||
qobject_cast<QLineEdit *>(this->findChild<QObject *>(constantTempLineEditName));
|
||||
if (constantTempLineEdit) {
|
||||
if (constantTempLineEdit)
|
||||
{
|
||||
constantTempLineEdit->setText(QString::number(phase.constant_temp_time_min));
|
||||
constantTempLineEdit->setEnabled(true);
|
||||
}
|
||||
QString atmoshpereComboBoxName = QString("comboBox_phase_%1_atmosphere").arg(i);
|
||||
QString atmoshpereComboBoxName = QString("comboBox_phase_%1_atmosphere").arg(i);
|
||||
QComboBox *atmoshpereComboBox =
|
||||
qobject_cast<QComboBox *>(this->findChild<QObject *>(atmoshpereComboBoxName));
|
||||
if (atmoshpereComboBox) {
|
||||
if (atmoshpereComboBox)
|
||||
{
|
||||
atmoshpereComboBox->setCurrentIndex(phase.gas % 256);
|
||||
atmoshpereComboBox->setEnabled(true);
|
||||
}
|
||||
@ -817,10 +924,13 @@ void ExperimentSettingForm::slotRecvPhaseInfo(const QByteArray &ba) {
|
||||
// radioButton_OIT
|
||||
// comboBox_initial_atmosphere
|
||||
|
||||
// 设置OIT类型
|
||||
u8 *oitValue = (data + 72);
|
||||
|
||||
logde << "oit value:" << (int)*oitValue;
|
||||
|
||||
if (*oitValue) {
|
||||
if (*oitValue)
|
||||
{
|
||||
ui->radioButton_OIT->setChecked(false);
|
||||
ui->radioButton_OIT_not->setChecked(true);
|
||||
#if 0
|
||||
@ -831,7 +941,9 @@ void ExperimentSettingForm::slotRecvPhaseInfo(const QByteArray &ba) {
|
||||
oitRadioButton->setChecked(true);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->radioButton_OIT->setChecked(true);
|
||||
ui->radioButton_OIT_not->setChecked(false);
|
||||
Global::_experimentOITFlag = true;
|
||||
@ -847,6 +959,7 @@ void ExperimentSettingForm::slotRecvPhaseInfo(const QByteArray &ba) {
|
||||
#endif
|
||||
}
|
||||
|
||||
// 设置默认其他类型。
|
||||
u8 *initAtmosphereValue = (data + 73);
|
||||
logde << "initAtmosphereValue:" << (int)(*initAtmosphereValue);
|
||||
ui->comboBox_initial_atmosphere->setCurrentIndex((int)*initAtmosphereValue);
|
||||
@ -861,9 +974,28 @@ void ExperimentSettingForm::slotRecvPhaseInfo(const QByteArray &ba) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void ExperimentSettingForm::showEvent(QShowEvent *event) {
|
||||
QDateTime currentDateTime = QDateTime::currentDateTime();
|
||||
QString internationalFormat = currentDateTime.toString("yyyy/MM/dd hh:mm:ss");
|
||||
void ExperimentSettingForm::showEvent(QShowEvent *event)
|
||||
{
|
||||
QDateTime currentDateTime = QDateTime::currentDateTime();
|
||||
QString internationalFormat = currentDateTime.toString("yyyy/MM/dd hh:mm:ss");
|
||||
|
||||
ui->dateTimeLineEdit->setText(internationalFormat);
|
||||
|
||||
// 测试类型OIT设置
|
||||
if (Global::_experimentInfo.testType == Global::TestType::OIT)
|
||||
{
|
||||
Global::_experimentOITFlag = true;
|
||||
|
||||
ui->radioButton_OIT->setChecked(true);
|
||||
ui->radioButton_OIT_not->setChecked(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
Global::_experimentOITFlag = false;
|
||||
|
||||
ui->radioButton_OIT->setChecked(false);
|
||||
ui->radioButton_OIT_not->setChecked(true);
|
||||
}
|
||||
// 初始气氛
|
||||
ui->comboBox_initial_atmosphere->setCurrentIndex((int)Global::_experimentInfo.initialAtmosPhere);
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
#include "leftwidget.h"
|
||||
#include "filemanager.h"
|
||||
#include "global.h"
|
||||
#include "logger.h"
|
||||
#include "../logger/logger.h"
|
||||
|
||||
LeftWidget::LeftWidget(QWidget *parent) : QDockWidget(parent)
|
||||
{
|
||||
@ -38,8 +38,13 @@ LeftWidget::LeftWidget(QWidget *parent) : QDockWidget(parent)
|
||||
_contextMenu = new QMenu(_treeWidget);
|
||||
_deleteFileAction = new QAction("删除文件", this);
|
||||
_createFolderAction = new QAction("新建文件夹", this);
|
||||
_moveToFolderAction = new QAction("移动到文件夹", this);
|
||||
_moveToFolderSubMenu = new QMenu("移动到文件夹", this); // Initialize submenu
|
||||
_moveToFolderAction->setMenu(_moveToFolderSubMenu); // Set submenu for move to folder action
|
||||
|
||||
_contextMenu->addAction(_deleteFileAction);
|
||||
_contextMenu->addAction(_createFolderAction);
|
||||
_contextMenu->addMenu(_moveToFolderSubMenu); // Add submenu instead of action
|
||||
|
||||
_treeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
|
||||
@ -50,20 +55,112 @@ LeftWidget::LeftWidget(QWidget *parent) : QDockWidget(parent)
|
||||
this, &LeftWidget::slotDeleteActionTriggered);
|
||||
connect(_createFolderAction, &QAction::triggered,
|
||||
this, &LeftWidget::slotCreateFolderActionTriggered);
|
||||
connect(_moveToFolderAction, &QAction::triggered,
|
||||
this, &LeftWidget::slotMoveToFolderActionTriggered); // Connect the move to folder action
|
||||
}
|
||||
|
||||
void LeftWidget::slotShowContextMenu(const QPoint &pos)
|
||||
{
|
||||
QTreeWidgetItem *item = _treeWidget->itemAt(pos);
|
||||
if (item)
|
||||
{
|
||||
// 获取文件路径
|
||||
QString filePath = item->data(0, Qt::UserRole).toString();
|
||||
QString dirPath = item->data(0, Qt::UserRole + 1).toString();
|
||||
|
||||
logde << "filePath:" << filePath.toStdString();
|
||||
logde << "dirPath:" << dirPath.toStdString();
|
||||
|
||||
// 如果是文件
|
||||
if (!filePath.isEmpty())
|
||||
{
|
||||
_deleteFileActionFilePath = filePath;
|
||||
_deleteFileAction->setVisible(true);
|
||||
_deleteFileAction->setText(tr("删除文件"));
|
||||
|
||||
// 显示移动到文件夹选项
|
||||
_moveToFolderAction->setVisible(true);
|
||||
|
||||
// 清除之前的子菜单项
|
||||
_moveToFolderSubMenu->clear();
|
||||
|
||||
// 获取根目录下的文件夹路径并创建子菜单项(只显示第一层文件夹)
|
||||
QStringList folderPaths = getRootFolderPaths();
|
||||
for (const QString &folderPath : folderPaths)
|
||||
{
|
||||
// 获取文件夹名称
|
||||
QString folderName = QFileInfo(folderPath).fileName();
|
||||
|
||||
// 创建子菜单项
|
||||
QAction *folderAction = new QAction(folderName, this);
|
||||
folderAction->setData(folderPath); // 将完整路径存储在action中
|
||||
|
||||
// 连接信号到槽
|
||||
connect(folderAction, &QAction::triggered, this, [this, folderAction]()
|
||||
{ slotMoveToSpecificFolder(folderAction->data().toString()); });
|
||||
|
||||
// 添加到子菜单
|
||||
_moveToFolderSubMenu->addAction(folderAction);
|
||||
}
|
||||
|
||||
// 如果没有可用文件夹,禁用移动功能
|
||||
if (folderPaths.isEmpty())
|
||||
{
|
||||
_moveToFolderAction->setEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
_moveToFolderAction->setEnabled(true);
|
||||
}
|
||||
}
|
||||
// 如果是目录
|
||||
else if (!dirPath.isEmpty())
|
||||
{
|
||||
// 不显示删除文件功能
|
||||
_deleteFileAction->setVisible(false);
|
||||
|
||||
// 不显示移动到文件夹功能(目录不能移动)
|
||||
_moveToFolderAction->setVisible(false);
|
||||
_moveToFolderAction->setEnabled(false);
|
||||
|
||||
#if 0
|
||||
_deleteFileAction->setVisible(true);
|
||||
_deleteFileActionFilePath = dirPath;
|
||||
_deleteFileAction->setText(tr("删除文件夹"));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// 对于根节点或其他项目,不显示移动功能
|
||||
_moveToFolderAction->setVisible(false);
|
||||
_moveToFolderAction->setEnabled(false);
|
||||
}
|
||||
|
||||
// 只有当点击的是目录时才显示"新建文件夹"选项
|
||||
bool isDir = !dirPath.isEmpty();
|
||||
_createFolderAction->setVisible(isDir);
|
||||
|
||||
_contextMenu->exec(_treeWidget->mapToGlobal(pos));
|
||||
}
|
||||
}
|
||||
|
||||
void LeftWidget::reloadFileName()
|
||||
{
|
||||
#if 0
|
||||
clearAllChildItems(_sampleDataItem);
|
||||
// clearAllChildItems(_baseLineItem);
|
||||
clearAllChildItems(_analysisStateItem);
|
||||
|
||||
initFileName(_sampleDataItem, Global::SampleDataFloder);
|
||||
|
||||
#if 0
|
||||
initFileName(_baseLineItem,Global::BaseLineFolder);
|
||||
#endif
|
||||
|
||||
initFileName(_analysisStateItem, Global::AnalysisStateFolder);
|
||||
#endif
|
||||
|
||||
reloadFileTree();
|
||||
// 更新文件列表
|
||||
Global::updateFileList();
|
||||
}
|
||||
@ -131,6 +228,7 @@ void LeftWidget::initData()
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void LeftWidget::slotTreeWidgetItemClicked(QTreeWidgetItem *item, int column)
|
||||
{
|
||||
qDebug() << "item clicked:" << item->text(0) << column;
|
||||
@ -237,80 +335,54 @@ void LeftWidget::recursiveFolderOperation(const QString& folderPath) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void LeftWidget::slotShowContextMenu(const QPoint &pos)
|
||||
{
|
||||
QTreeWidgetItem *item = _treeWidget->itemAt(pos);
|
||||
if (item) {
|
||||
// 获取文件路径
|
||||
QString filePath = item->data(0, Qt::UserRole).toString();
|
||||
QString dirPath = item->data(0, Qt::UserRole + 1).toString();
|
||||
|
||||
// 如果是文件
|
||||
if (!filePath.isEmpty()) {
|
||||
_deleteFileActionFilePath = filePath;
|
||||
_deleteFileAction->setVisible(true);
|
||||
_deleteFileAction->setText(tr("删除文件"));
|
||||
}
|
||||
// 如果是目录
|
||||
else if (!dirPath.isEmpty()) {
|
||||
// 暂时不要删除文件件功能
|
||||
_deleteFileAction->setVisible(false);
|
||||
#if 0
|
||||
_deleteFileAction->setVisible(true);
|
||||
_deleteFileActionFilePath = dirPath;
|
||||
_deleteFileAction->setText(tr("删除文件夹"));
|
||||
#endif
|
||||
} else {
|
||||
_deleteFileAction->setVisible(false);
|
||||
}
|
||||
|
||||
// 只有当点击的是目录时才显示"新建文件夹"选项
|
||||
bool isDir = !dirPath.isEmpty();
|
||||
_createFolderAction->setVisible(isDir);
|
||||
|
||||
_contextMenu->exec(_treeWidget->mapToGlobal(pos));
|
||||
}
|
||||
}
|
||||
|
||||
void LeftWidget::slotDeleteActionTriggered()
|
||||
{
|
||||
if (_deleteFileActionFilePath.isEmpty()) {
|
||||
if (_deleteFileActionFilePath.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
QFileInfo fileInfo(_deleteFileActionFilePath);
|
||||
bool isDir = fileInfo.isDir();
|
||||
|
||||
|
||||
// 检查文件/目录是否存在
|
||||
if (!fileInfo.exists()) {
|
||||
if (!fileInfo.exists())
|
||||
{
|
||||
QMessageBox::warning(this, tr("警告"), tr("文件/目录不存在!"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 确认删除对话框
|
||||
int ret = QMessageBox::question(this, tr("确认删除"),
|
||||
tr("确定要删除%1\n%2?").arg(isDir ? tr("文件夹及其所有内容") : tr("文件")).arg(_deleteFileActionFilePath),
|
||||
QMessageBox::Yes | QMessageBox::No,
|
||||
QMessageBox::No);
|
||||
|
||||
if (ret == QMessageBox::Yes) {
|
||||
int ret = QMessageBox::question(this, tr("确认删除"),
|
||||
tr("确定要删除%1\n%2?").arg(isDir ? tr("文件夹及其所有内容") : tr("文件")).arg(_deleteFileActionFilePath),
|
||||
QMessageBox::Yes | QMessageBox::No,
|
||||
QMessageBox::No);
|
||||
|
||||
if (ret == QMessageBox::Yes)
|
||||
{
|
||||
bool success;
|
||||
if (isDir) {
|
||||
if (isDir)
|
||||
{
|
||||
// 删除目录及其内容
|
||||
success = removeDir(_deleteFileActionFilePath);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
// 删除文件
|
||||
success = QFile::remove(_deleteFileActionFilePath);
|
||||
}
|
||||
|
||||
if (success) {
|
||||
|
||||
if (success)
|
||||
{
|
||||
// 重新加载文件树
|
||||
reloadFileTree();
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::critical(this, tr("错误"), tr("删除失败!"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_deleteFileActionFilePath.clear();
|
||||
}
|
||||
|
||||
@ -318,83 +390,96 @@ bool LeftWidget::removeDir(const QString &dirPath)
|
||||
{
|
||||
bool result = true;
|
||||
QDir dir(dirPath);
|
||||
|
||||
if (dir.exists(dirPath)) {
|
||||
Q_FOREACH(QFileInfo info, dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst)) {
|
||||
if (info.isDir()) {
|
||||
|
||||
if (dir.exists(dirPath))
|
||||
{
|
||||
Q_FOREACH (QFileInfo info, dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst))
|
||||
{
|
||||
if (info.isDir())
|
||||
{
|
||||
result = removeDir(info.absoluteFilePath());
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
result = QFile::remove(info.absoluteFilePath());
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
result = dir.rmdir(dirPath);
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void LeftWidget::slotCreateFolderActionTriggered()
|
||||
{
|
||||
// 获取当前选中的项目
|
||||
QTreeWidgetItem *currentItem = _treeWidget->currentItem();
|
||||
if (!currentItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 创建主分支下的文件夹
|
||||
QTreeWidgetItem *currentItem = _treeWidget->topLevelItem(0);
|
||||
logde << "currentItem : " << currentItem->text(0).toStdString();
|
||||
|
||||
// 获取当前目录路径
|
||||
QString dirPath;
|
||||
if (currentItem->data(0, Qt::UserRole + 1).toString().isEmpty()) {
|
||||
if (currentItem->data(0, Qt::UserRole + 1).toString().isEmpty())
|
||||
{
|
||||
// 如果是文件,获取其父目录
|
||||
dirPath = QFileInfo(currentItem->data(0, Qt::UserRole).toString()).absolutePath();
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果是目录,直接使用其路径
|
||||
dirPath = currentItem->data(0, Qt::UserRole + 1).toString();
|
||||
}
|
||||
|
||||
|
||||
// 弹出对话框,输入新文件夹名称
|
||||
bool ok;
|
||||
QString folderName = QInputDialog::getText(this, tr("新建文件夹"),
|
||||
tr("请输入文件夹名称:"),
|
||||
QLineEdit::Normal,
|
||||
QString folderName = QInputDialog::getText(this, tr("新建文件夹"),
|
||||
tr("请输入文件夹名称:"),
|
||||
QLineEdit::Normal,
|
||||
tr("新建文件夹"), &ok);
|
||||
|
||||
if (!ok || folderName.isEmpty()) {
|
||||
|
||||
if (!ok || folderName.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 检查文件夹名称是否有效
|
||||
if (folderName.contains(QRegExp("[\\/:*?\"<>|]"))) {
|
||||
if (folderName.contains(QRegExp("[\\/:*?\"<>|]")))
|
||||
{
|
||||
QMessageBox::warning(this, tr("错误"), tr("文件夹名称包含非法字符!"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 创建新文件夹路径
|
||||
QString newFolderPath = dirPath + "/" + folderName;
|
||||
|
||||
|
||||
// 检查文件夹是否已存在
|
||||
if (QDir(newFolderPath).exists()) {
|
||||
if (QDir(newFolderPath).exists())
|
||||
{
|
||||
QMessageBox::warning(this, tr("错误"), tr("文件夹已存在!"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 创建文件夹
|
||||
if (QDir().mkdir(newFolderPath)) {
|
||||
if (QDir().mkdir(newFolderPath))
|
||||
{
|
||||
// 保存当前展开状态
|
||||
saveExpandedState();
|
||||
|
||||
|
||||
// 重新加载文件树
|
||||
reloadFileTree();
|
||||
|
||||
|
||||
// 恢复展开状态
|
||||
restoreExpandedState();
|
||||
|
||||
|
||||
// 展开当前目录并选中新创建的文件夹
|
||||
expandAndSelectItem(newFolderPath);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::critical(this, tr("错误"), tr("创建文件夹失败!"));
|
||||
}
|
||||
}
|
||||
@ -403,18 +488,21 @@ void LeftWidget::expandAndSelectItem(const QString &path)
|
||||
{
|
||||
// 递归展开到指定路径并选中该项
|
||||
QTreeWidgetItemIterator it(_treeWidget);
|
||||
while (*it) {
|
||||
while (*it)
|
||||
{
|
||||
QTreeWidgetItem *item = *it;
|
||||
QString itemPath = item->data(0, Qt::UserRole + 1).toString();
|
||||
|
||||
if (itemPath == path) {
|
||||
|
||||
if (itemPath == path)
|
||||
{
|
||||
// 展开所有父节点
|
||||
QTreeWidgetItem *parent = item->parent();
|
||||
while (parent) {
|
||||
while (parent)
|
||||
{
|
||||
parent->setExpanded(true);
|
||||
parent = parent->parent();
|
||||
}
|
||||
|
||||
|
||||
// 选中新创建的文件夹
|
||||
_treeWidget->setCurrentItem(item);
|
||||
break;
|
||||
@ -446,26 +534,26 @@ void LeftWidget::reloadFileTree()
|
||||
{
|
||||
// 保存当前展开状态
|
||||
saveExpandedState();
|
||||
|
||||
|
||||
// 清空现有的树形结构
|
||||
_treeWidget->clear();
|
||||
|
||||
|
||||
// 创建根节点
|
||||
QTreeWidgetItem *rootItem = new QTreeWidgetItem(_treeWidget);
|
||||
rootItem->setText(0, "实验数据");
|
||||
rootItem->setData(0, Qt::UserRole, Global::ExperimentDirPath);
|
||||
// rootItem->setData(0, Qt::UserRole, Global::ExperimentDirPath);
|
||||
// 保存根目录路径,用于恢复展开状态
|
||||
rootItem->setData(0, Qt::UserRole + 1, Global::ExperimentDirPath);
|
||||
|
||||
|
||||
// 递归扫描目录并构建树形结构
|
||||
buildFileTree(rootItem, Global::ExperimentDirPath);
|
||||
|
||||
|
||||
// 展开根节点
|
||||
rootItem->setExpanded(true);
|
||||
|
||||
|
||||
// 恢复展开状态
|
||||
restoreExpandedState();
|
||||
|
||||
|
||||
// 更新全局文件列表
|
||||
Global::updateFileList();
|
||||
}
|
||||
@ -487,39 +575,47 @@ QFileInfoList LeftWidget::scanDirRecursively(const QString &rootPath)
|
||||
void LeftWidget::buildFileTree(QTreeWidgetItem *parentItem, const QString &dirPath)
|
||||
{
|
||||
QDir dir(dirPath);
|
||||
if (!dir.exists()) {
|
||||
if (!dir.exists())
|
||||
{
|
||||
qWarning() << "目录不存在: " << dirPath;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 获取所有子目录和文件,按名称排序
|
||||
dir.setSorting(QDir::Name | QDir::DirsFirst);
|
||||
QFileInfoList list = dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
|
||||
|
||||
for (const QFileInfo &fileInfo : list) {
|
||||
|
||||
for (const QFileInfo &fileInfo : list)
|
||||
{
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem(parentItem);
|
||||
|
||||
if (fileInfo.isDir()) {
|
||||
|
||||
if (fileInfo.isDir())
|
||||
{
|
||||
// 设置目录项
|
||||
item->setText(0, fileInfo.fileName());
|
||||
// 使用系统默认的目录图标
|
||||
item->setIcon(0, _treeWidget->style()->standardIcon(QStyle::SP_DirIcon));
|
||||
// 保存目录路径,用于恢复展开状态
|
||||
item->setData(0, Qt::UserRole + 1, fileInfo.absoluteFilePath());
|
||||
|
||||
|
||||
// 递归处理子目录
|
||||
buildFileTree(item, fileInfo.absoluteFilePath());
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
// 设置文件项
|
||||
item->setText(0, fileInfo.fileName());
|
||||
item->setData(0, Qt::UserRole, fileInfo.absoluteFilePath());
|
||||
|
||||
|
||||
// 根据文件类型设置不同的图标
|
||||
QString suffix = fileInfo.suffix().toLower();
|
||||
if (suffix == "xlsx" || suffix == "xls") {
|
||||
if (suffix == "xlsx" || suffix == "xls")
|
||||
{
|
||||
// 使用系统默认的文档图标
|
||||
item->setIcon(0, _treeWidget->style()->standardIcon(QStyle::SP_FileIcon));
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
// 使用默认文件图标
|
||||
item->setIcon(0, _treeWidget->style()->standardIcon(QStyle::SP_FileIcon));
|
||||
}
|
||||
@ -530,41 +626,179 @@ void LeftWidget::buildFileTree(QTreeWidgetItem *parentItem, const QString &dirPa
|
||||
void LeftWidget::saveExpandedState()
|
||||
{
|
||||
_expandedPaths.clear();
|
||||
|
||||
|
||||
// 递归遍历所有项,保存展开的目录路径
|
||||
QTreeWidgetItemIterator it(_treeWidget);
|
||||
while (*it) {
|
||||
while (*it)
|
||||
{
|
||||
QTreeWidgetItem *item = *it;
|
||||
if (item->isExpanded()) {
|
||||
if (item->isExpanded())
|
||||
{
|
||||
QVariant pathData = item->data(0, Qt::UserRole + 1);
|
||||
if (!pathData.isNull()) {
|
||||
if (!pathData.isNull())
|
||||
{
|
||||
_expandedPaths.append(pathData.toString());
|
||||
}
|
||||
}
|
||||
++it;
|
||||
}
|
||||
|
||||
|
||||
qDebug() << "保存了" << _expandedPaths.size() << "个展开状态:" << _expandedPaths;
|
||||
}
|
||||
|
||||
void LeftWidget::restoreExpandedState()
|
||||
{
|
||||
int restoredCount = 0;
|
||||
|
||||
|
||||
// 递归遍历所有项,恢复展开状态
|
||||
QTreeWidgetItemIterator it(_treeWidget);
|
||||
while (*it) {
|
||||
while (*it)
|
||||
{
|
||||
QTreeWidgetItem *item = *it;
|
||||
QVariant pathData = item->data(0, Qt::UserRole + 1);
|
||||
if (!pathData.isNull()) {
|
||||
if (!pathData.isNull())
|
||||
{
|
||||
QString path = pathData.toString();
|
||||
if (_expandedPaths.contains(path)) {
|
||||
if (_expandedPaths.contains(path))
|
||||
{
|
||||
item->setExpanded(true);
|
||||
restoredCount++;
|
||||
}
|
||||
}
|
||||
++it;
|
||||
}
|
||||
|
||||
|
||||
qDebug() << "恢复了" << restoredCount << "个展开状态";
|
||||
}
|
||||
|
||||
void LeftWidget::slotMoveToFolderActionTriggered()
|
||||
{
|
||||
// 获取当前选中的项目
|
||||
QTreeWidgetItem *currentItem = _treeWidget->currentItem();
|
||||
if (!currentItem)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查是否是文件(不能移动文件夹)
|
||||
QString filePath = currentItem->data(0, Qt::UserRole).toString();
|
||||
if (filePath.isEmpty())
|
||||
{
|
||||
QMessageBox::information(this, tr("提示"), tr("请选择一个文件进行移动!"));
|
||||
return;
|
||||
}
|
||||
|
||||
// 弹出对话框让用户选择目标文件夹
|
||||
QStringList folderPaths = getAllFolderPaths();
|
||||
|
||||
bool ok;
|
||||
QString selectedPath = QInputDialog::getItem(this,
|
||||
tr("选择目标文件夹"),
|
||||
tr("请选择要移动到的目标文件夹:"),
|
||||
folderPaths,
|
||||
0,
|
||||
false,
|
||||
&ok);
|
||||
|
||||
if (!ok || selectedPath.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
slotMoveToSpecificFolder(selectedPath);
|
||||
}
|
||||
|
||||
void LeftWidget::slotMoveToSpecificFolder(const QString &targetFolderPath)
|
||||
{
|
||||
// 获取当前选中的项目
|
||||
QTreeWidgetItem *currentItem = _treeWidget->currentItem();
|
||||
if (!currentItem)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查是否是文件(不能移动文件夹)
|
||||
QString filePath = currentItem->data(0, Qt::UserRole).toString();
|
||||
if (filePath.isEmpty())
|
||||
{
|
||||
QMessageBox::information(this, tr("提示"), tr("请选择一个文件进行移动!"));
|
||||
return;
|
||||
}
|
||||
|
||||
// 保存要移动的文件路径
|
||||
QString fileToMove = filePath;
|
||||
|
||||
// 执行移动操作
|
||||
QString targetPath = targetFolderPath + "/" + QFileInfo(fileToMove).fileName();
|
||||
|
||||
// 检查目标文件是否已存在
|
||||
if (QFile::exists(targetPath))
|
||||
{
|
||||
int ret = QMessageBox::question(this, tr("确认覆盖"),
|
||||
tr("目标文件已存在,是否覆盖?\n%1").arg(targetPath),
|
||||
QMessageBox::Yes | QMessageBox::No,
|
||||
QMessageBox::No);
|
||||
if (ret == QMessageBox::No)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 移动文件
|
||||
if (QFile::rename(fileToMove, targetPath))
|
||||
{
|
||||
logde << "文件移动成功: " << fileToMove.toStdString() << " -> " << targetPath.toStdString();
|
||||
|
||||
// 保存当前展开状态
|
||||
saveExpandedState();
|
||||
// 重新加载文件树
|
||||
reloadFileTree();
|
||||
// 恢复展开状态
|
||||
restoreExpandedState();
|
||||
|
||||
// 展开并选中目标文件夹
|
||||
expandAndSelectItem(targetFolderPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::critical(this, tr("错误"), tr("文件移动失败!"));
|
||||
}
|
||||
}
|
||||
|
||||
QStringList LeftWidget::getRootFolderPaths()
|
||||
{
|
||||
QStringList folderPaths;
|
||||
|
||||
QDir rootDir(Global::ExperimentDirPath);
|
||||
if (rootDir.exists())
|
||||
{
|
||||
// Get only directories in the root path (no recursion)
|
||||
QFileInfoList entries = rootDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
for (const QFileInfo &entry : entries)
|
||||
{
|
||||
folderPaths << entry.absoluteFilePath();
|
||||
}
|
||||
}
|
||||
|
||||
return folderPaths;
|
||||
}
|
||||
|
||||
QStringList LeftWidget::getAllFolderPaths()
|
||||
{
|
||||
QStringList folderPaths;
|
||||
|
||||
// 递归遍历所有项目以获取所有文件夹路径
|
||||
QTreeWidgetItemIterator it(_treeWidget);
|
||||
while (*it)
|
||||
{
|
||||
QTreeWidgetItem *item = *it;
|
||||
QString dirPath = item->data(0, Qt::UserRole + 1).toString();
|
||||
if (!dirPath.isEmpty())
|
||||
{
|
||||
folderPaths << dirPath;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
|
||||
return folderPaths;
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
|
||||
#include "global.h"
|
||||
|
||||
class LeftWidget:public QDockWidget
|
||||
class LeftWidget : public QDockWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
@ -21,44 +21,56 @@ public:
|
||||
|
||||
void reloadFileTree();
|
||||
|
||||
QString filePathCheck(const QString fileName,const QString folderPath);
|
||||
QString filePathCheck(const QString fileName, const QString folderPath);
|
||||
|
||||
// 确认删除文件
|
||||
void confirmDelete(bool enabled);
|
||||
signals:
|
||||
void sigSendAnalysisFileName(const QString&);
|
||||
void sigDeleteActionTriggered(const QString&);
|
||||
void sigSendAnalysisFileName(const QString &);
|
||||
void sigDeleteActionTriggered(const QString &);
|
||||
|
||||
private:
|
||||
void initData();
|
||||
void initFileName(QTreeWidgetItem*,const QString &folderPath);
|
||||
void expandAll(QTreeWidgetItem* item);
|
||||
void clearAllChildItems(QTreeWidgetItem* parentItem);
|
||||
void initFileName(QTreeWidgetItem *, const QString &folderPath);
|
||||
void expandAll(QTreeWidgetItem *item);
|
||||
void clearAllChildItems(QTreeWidgetItem *parentItem);
|
||||
QFileInfoList scanDirRecursively(const QString &rootPath);
|
||||
void buildFileTree(QTreeWidgetItem *parentItem, const QString &dirPath);
|
||||
void saveExpandedState();
|
||||
void restoreExpandedState();
|
||||
void expandAndSelectItem(const QString &path);
|
||||
bool removeDir(const QString &dirPath);
|
||||
QStringList getAllFolderPaths(); // Add function to get all folder paths for move operation
|
||||
QStringList getRootFolderPaths(); // Add function to get only root level folder paths
|
||||
private slots:
|
||||
void slotTreeWidgetItemClicked(QTreeWidgetItem *item, int column);
|
||||
// 右键菜单
|
||||
void slotShowContextMenu(const QPoint &pos);
|
||||
void slotDeleteActionTriggered();
|
||||
void slotCreateFolderActionTriggered();
|
||||
void slotMoveToFolderActionTriggered(); // Add slot for move to folder action
|
||||
void slotMoveToSpecificFolder(const QString &targetFolderPath); // 新增:移动到指定文件夹的槽函数
|
||||
|
||||
private:
|
||||
QTreeWidget *_treeWidget;
|
||||
|
||||
|
||||
#if 0
|
||||
QTreeWidgetItem *_analysisStateItem,
|
||||
*_baseLineItem,
|
||||
*_sampleDataItem;
|
||||
*_baseLineItem,
|
||||
*_sampleDataItem;
|
||||
#endif
|
||||
|
||||
QMenu *_contextMenu;
|
||||
|
||||
|
||||
QAction *_deleteFileAction;
|
||||
QAction *_createFolderAction;
|
||||
QAction *_moveToFolderAction;
|
||||
QMenu *_moveToFolderSubMenu; // Add submenu for move to folder
|
||||
|
||||
QString _deleteFileActionFilePath;
|
||||
|
||||
|
||||
// 保存展开状态的列表
|
||||
QStringList _expandedPaths;
|
||||
};
|
||||
|
||||
#endif // LEFTWIDGET_H
|
||||
|
||||
#endif // LEFTWIDGET_H
|
||||
@ -84,7 +84,6 @@ void PrintPreviewForm::slotPaintRequested(QPrinter *printer) {
|
||||
painter.setOpacity(1.0);
|
||||
#endif
|
||||
|
||||
|
||||
// 获取页面矩形区域
|
||||
QRect pageRect = printer->pageRect();
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user