2025-12-26T17:29:18

This commit is contained in:
yuntang 2025-12-26 17:29:18 +08:00
parent 0583d5f84f
commit 44fc93eb4e
25 changed files with 1266 additions and 683 deletions

View File

@ -5,6 +5,37 @@
"string": "cpp", "string": "cpp",
"string_view": "cpp", "string_view": "cpp",
"deque": "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"
} }
} }

View File

@ -9,7 +9,7 @@ CONFIG+=precompile_header
PRECOMPILED_HEADER=stable.h PRECOMPILED_HEADER=stable.h
# #
VERSION = 1.4.0 VERSION = 1.3.9
# 设置目标文件名,包含版本号 # 设置目标文件名,包含版本号
TARGET = DSCAnalysisTool_$${VERSION} TARGET = DSCAnalysisTool_$${VERSION}

View File

@ -96,7 +96,10 @@ namespace Global {
QVector<Phase> phaseVtr; QVector<Phase> phaseVtr;
ExperimentInfo() ExperimentInfo()
: sampleName("new"), sampleWeight("0"), date("20250101"), experimentor("experimentor") {} : sampleName("new"),
sampleWeight("0"),
date("20250101"),
experimentor("experimentor") {}
}; };
struct PhaseTotalInfo { struct PhaseTotalInfo {
@ -180,6 +183,7 @@ extern QString _smoothnessFileName;
void updateFileList(); void updateFileList();
bool isFileExist(const QString &fileName); bool isFileExist(const QString &fileName);
}; // namespace Global }; // namespace Global
#endif // GLOBAL_H #endif // GLOBAL_H

View File

@ -1,7 +1,7 @@
#ifndef LOGGER_H #ifndef LOGGER_H
#define LOGGER_H #define LOGGER_H
#include "easylogging++.h" #include "../thirdparty/easylogging/easylogging++.h"
#define logde LOG(DEBUG) #define logde LOG(DEBUG)
#define loger LOG(ERROR) #define loger LOG(ERROR)

View File

@ -27,6 +27,7 @@ int main(int argc, char *argv[])
// 启用高DPI支持 // 启用高DPI支持
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); // 启用高DPI缩放 QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); // 启用高DPI缩放
QApplication a(argc, argv); QApplication a(argc, argv);
logde<<"version:"<<a.applicationVersion().toStdString(); logde<<"version:"<<a.applicationVersion().toStdString();

View File

@ -37,8 +37,6 @@ bool commonDataParser(const QByteArray &ba, CommonData &cd)
return true; return true;
} }
QByteArray setExperimentInfo(const QVector<Phase> &vtr, const QByteArray initBa) QByteArray setExperimentInfo(const QVector<Phase> &vtr, const QByteArray initBa)
{ {
// const int phaseLength = sizeof(Phase); // const int phaseLength = sizeof(Phase);
@ -54,7 +52,6 @@ QByteArray setExperimentInfo(const QVector<Phase> &vtr,const QByteArray initBa)
offset += phaseLength; offset += phaseLength;
} }
//
// int totalDataLength = 0; // int totalDataLength = 0;
char totalData[300] = {}; char totalData[300] = {};
@ -143,7 +140,8 @@ QByteArray setDeviceStartStop(const DeviceStartMode mode)
void experimentalStateSwitching(const CommonData &cd) void experimentalStateSwitching(const CommonData &cd)
{ {
// Switch the software mode accord to the serial port data. // Switch the software mode accord to the serial port data.
switch(cd.run_type){ switch (cd.run_type)
{
case DeviceRunStatus::Heat: case DeviceRunStatus::Heat:
case DeviceRunStatus::ConstantTemp: case DeviceRunStatus::ConstantTemp:
Global::_mode = Global::Mode::Experiment; Global::_mode = Global::Mode::Experiment;
@ -153,7 +151,8 @@ void experimentalStateSwitching(const CommonData &cd)
Global::_mode = Global::Mode::Analysis; Global::_mode = Global::Mode::Analysis;
break; break;
default:break; default:
break;
} }
#if 0 #if 0
@ -186,6 +185,7 @@ unsigned short modbusCRC16(unsigned char *data, unsigned short length)
return crc; return crc;
} }
// 请求实验参数
QByteArray inquirePhaseInfo() QByteArray inquirePhaseInfo()
{ {
SerialPortProtocol spp; SerialPortProtocol spp;
@ -204,7 +204,4 @@ QByteArray inquirePhaseInfo()
QByteArray((char *)&crc, 2); QByteArray((char *)&crc, 2);
} }
}; };

View File

@ -21,3 +21,8 @@ unsigned short modbusCRC16(unsigned char *data,unsigned short length);
} }
#endif // DATAPARSER_H #endif // DATAPARSER_H
/**
*/

View File

@ -3,7 +3,7 @@
#include <cstdint> #include <cstdint>
#define FRANE_HEAD 0x5AA5 // #define FRANE_HEAD 0x5AA5 //
#define WRITE_CMD 0x82 //写指令 #define WRITE_CMD 0x82 //写指令
#define READ_CMD 0x83 //读指令 #define READ_CMD 0x83 //读指令
@ -59,6 +59,7 @@ struct pid_data
float kd; float kd;
}; };
#if 0
typedef struct com_data typedef struct com_data
{ {
uint8_t run_type; //0,运行状态 uint8_t run_type; //0,运行状态
@ -99,6 +100,52 @@ typedef struct com_data
float enthalpy_equation_b; //热焓方程式系数b float enthalpy_equation_b; //热焓方程式系数b
float enthalpy_equation_c; //热焓方程式系数c float enthalpy_equation_c; //热焓方程式系数c
} CommonData; } 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) #pragma pack(pop)

View File

@ -20,7 +20,8 @@ const u16 conPid = 22336; // 0x5740
SerialPort::SerialPort(QObject *parent) SerialPort::SerialPort(QObject *parent)
: QObject(parent), _sp(new QSerialPort(this)), : QObject(parent), _sp(new QSerialPort(this)),
_portCheckTimer(new QTimer(this)) { _portCheckTimer(new QTimer(this))
{
// //
connect(_portCheckTimer, &QTimer::timeout, connect(_portCheckTimer, &QTimer::timeout,
this, &SerialPort::slotPortCheck); this, &SerialPort::slotPortCheck);
@ -77,12 +78,14 @@ SerialPort::SerialPort(QObject *parent)
#endif #endif
} }
SerialPort *SerialPort::instance() { SerialPort *SerialPort::instance()
{
static SerialPort ins; static SerialPort ins;
return &ins; return &ins;
} }
SerialPort::~SerialPort() { SerialPort::~SerialPort()
{
logde << "serialport destructor."; logde << "serialport destructor.";
closeSp(); closeSp();
@ -95,9 +98,11 @@ SerialPort::~SerialPort() {
_portCheckTimer = nullptr; _portCheckTimer = nullptr;
} }
void SerialPort::slotReadData() { void SerialPort::slotReadData()
{
QByteArray ba = _sp->readAll(); QByteArray ba = _sp->readAll();
if (ba.size() == 0) { if (ba.size() == 0)
{
return; return;
} }
@ -107,42 +112,74 @@ void SerialPort::slotReadData() {
#endif #endif
SerialPortProtocol *spp = (SerialPortProtocol *)ba.data(); SerialPortProtocol *spp = (SerialPortProtocol *)ba.data();
if (FRANE_HEAD != spp->head) { if (FRANE_HEAD != spp->head)
{
logde << "Data header error."; logde << "Data header error.";
return; return;
} }
// phase setting data // 实验阶段数据设置
if (spp->addr == PHASE_START_ADDR) { if (spp->addr == PHASE_START_ADDR)
{
emit sigSendPhaseInfo(ba); emit sigSendPhaseInfo(ba);
return; return;
} }
int dataLength = spp->len - 5; int dataLength = spp->len - 5;
// 非实验阶段数据解析
CommonData cd; CommonData cd;
u8 *cdPtr = (u8 *)&cd; u8 *cdPtr = (u8 *)&cd;
memcpy(cdPtr + spp->addr, spp->data_buf, dataLength); 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); 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); // DataParser::experimentalStateSwitching(cd);
updateStatus(cd); updateStatus(cd);
if (spp->addr == 0) { if (spp->addr == 0)
if (Global::Mode::Experiment == Global::_mode) { {
if (Global::Mode::Experiment == Global::_mode)
{
emit sigSendCommonData(cd); emit sigSendCommonData(cd);
} }
// emit sigSendCommonDataToRealDataForm(cd); // emit sigSendCommonDataToRealDataForm(cd);
} else { }
else
{
QString hexData = ba.toHex(' '); // ' ' 作为分隔符,可选参数 QString hexData = ba.toHex(' '); // ' ' 作为分隔符,可选参数
logde << "receive info (hex):" << hexData.toStdString(); logde << "receive info (hex):" << hexData.toStdString();
} }
} }
} }
void SerialPort::updateStatus(const CommonData &cd) { void SerialPort::updateStatus(const CommonData &cd)
{
#if 0 #if 0
// logde<<"phase:"<<(int)cd.current_phase; // logde<<"phase:"<<(int)cd.current_phase;
// logde<<"run type:"<<(int)cd.run_type; // logde<<"run type:"<<(int)cd.run_type;
@ -150,16 +187,19 @@ void SerialPort::updateStatus(const CommonData &cd) {
#endif #endif
// Switch the software mode accord to the serial port data. // Switch the software mode accord to the serial port data.
switch (cd.run_type) { switch (cd.run_type)
{
case DeviceRunStatus::Heat: case DeviceRunStatus::Heat:
case DeviceRunStatus::ConstantTemp: case DeviceRunStatus::ConstantTemp:
if (Global::_mode != Global::Mode::Experiment) { if (Global::_mode != Global::Mode::Experiment)
{
Global::_mode = Global::Mode::Experiment; Global::_mode = Global::Mode::Experiment;
} }
break; break;
case DeviceRunStatus::Idle: case DeviceRunStatus::Idle:
case DeviceRunStatus::Cooling: case DeviceRunStatus::Cooling:
if (Global::_mode != Global::Mode::Analysis) { if (Global::_mode != Global::Mode::Analysis)
{
Global::_mode = Global::Mode::Analysis; Global::_mode = Global::Mode::Analysis;
} }
break; break;
@ -170,12 +210,14 @@ void SerialPort::updateStatus(const CommonData &cd) {
// 判断是否根据下位机数据,切换软件实验模式。 // 判断是否根据下位机数据,切换软件实验模式。
static Global::Mode preMode = Global::Mode::Analysis; static Global::Mode preMode = Global::Mode::Analysis;
bool sendSaveSignalFlag = false; bool sendSaveSignalFlag = false;
if (Global::_mode != preMode) { if (Global::_mode != preMode)
if (preMode == Global::Mode::Experiment {
&& Global::_mode == Global::Mode::Analysis) { if (preMode == Global::Mode::Experiment && Global::_mode == Global::Mode::Analysis)
{
sendSaveSignalFlag = true; 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..."; 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 phase update, add new phase data to the global param.
if (Global::_mode == Global::Mode::Experiment) { if (Global::_mode == Global::Mode::Experiment)
if (Global::_currentPhase != (int)cd.current_phase) { {
if (Global::_currentPhase != (int)cd.current_phase)
{
logde << "mode experiment,phase not equeal."; logde << "mode experiment,phase not equeal.";
@ -217,7 +261,8 @@ void SerialPort::updateStatus(const CommonData &cd) {
// Update axis. // Update axis.
bool experimentEnded = false; bool experimentEnded = false;
QString devRunModeStr; QString devRunModeStr;
switch (cd.run_type) { switch (cd.run_type)
{
case DeviceRunStatus::Heat: case DeviceRunStatus::Heat:
devRunModeStr = "升温"; devRunModeStr = "升温";
experimentEnded = true; experimentEnded = true;
@ -237,9 +282,12 @@ void SerialPort::updateStatus(const CommonData &cd) {
} }
QString msg; QString msg;
if (experimentEnded) { if (experimentEnded)
{
msg = QString("设备运行状态:%2 实验阶段:%3 实验进行中").arg(devRunModeStr).arg(cd.current_phase); 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 实验阶段:%3 实验结束").arg(devRunModeStr).arg(cd.current_phase);
msg = QString("设备运行状态:%2 实验结束").arg(devRunModeStr); msg = QString("设备运行状态:%2 实验结束").arg(devRunModeStr);
} }
@ -269,18 +317,26 @@ void SerialPort::updateStatus(const CommonData &cd) {
#endif #endif
// 弹出保存数据对话框。 // 弹出保存数据对话框。
if (sendSaveSignalFlag && !Global::_OITAutoAnalysisModeFlag) { if (sendSaveSignalFlag && !Global::_OITAutoAnalysisModeFlag)
{
emit sigSaveExperimentalDataMsgBox(); emit sigSaveExperimentalDataMsgBox();
} }
} }
// 解析下位机数据,更新全局参数。
void SerialPort::commonDataParser(const int dataLength, const u16 addr, void SerialPort::commonDataParser(const int dataLength, const u16 addr,
const CommonData &cd) { const CommonData &cd)
{
int localLength = dataLength; int localLength = dataLength;
int localAddr = addr; int localAddr = addr;
logde << "localLength total:" << localLength;
logde << "localAddr total:" << localAddr;
int phaseByteSize = sizeof(Phase); int phaseByteSize = sizeof(Phase);
auto phaseParserFunc = [&](const int index) { auto phaseParserFunc = [&](const int index)
{
Phase phase; Phase phase;
phase.onoff = 1; phase.onoff = 1;
phase.gas = cd.phase_data[index].gas; phase.gas = cd.phase_data[index].gas;
@ -293,12 +349,17 @@ void SerialPort::commonDataParser(const int dataLength, const u16 addr,
localAddr += phaseByteSize; localAddr += phaseByteSize;
}; };
while (localLength) { logde << "init_gas offset:" << offsetof(CommonData, init_gas);
while (localLength)
{
logde << "localLength:" << localLength; logde << "localLength:" << localLength;
switch (localAddr) { switch (localAddr)
{
case offsetof(CommonData, run_type): // 运行状态 case offsetof(CommonData, run_type): // 运行状态
{ {
switch (cd.run_type) { switch (cd.run_type)
{
case DeviceRunStatus::Cooling: case DeviceRunStatus::Cooling:
// Global::instance()->setMode(Global::Mode::Analysis); // Global::instance()->setMode(Global::Mode::Analysis);
Global::_mode = Global::Mode::Analysis; Global::_mode = Global::Mode::Analysis;
@ -322,10 +383,12 @@ void SerialPort::commonDataParser(const int dataLength, const u16 addr,
localAddr += 4; localAddr += 4;
localLength -= 4; localLength -= 4;
break; break;
case offsetof(CommonData, run_mode): { case offsetof(CommonData, run_mode):
{
DeviceStartMode mode = (DeviceStartMode)cd.run_mode; DeviceStartMode mode = (DeviceStartMode)cd.run_mode;
switch (mode) { switch (mode)
{
case DeviceStartMode::Stop: case DeviceStartMode::Stop:
Global::_mode = Global::Mode::Analysis; Global::_mode = Global::Mode::Analysis;
logde << "set global mode analysis."; logde << "set global mode analysis.";
@ -360,6 +423,20 @@ void SerialPort::commonDataParser(const int dataLength, const u16 addr,
case offsetof(CommonData, phase_data[5].onoff): case offsetof(CommonData, phase_data[5].onoff):
phaseParserFunc(5); phaseParserFunc(5);
break; 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: default:
localLength--; localLength--;
break; break;
@ -367,7 +444,8 @@ void SerialPort::commonDataParser(const int dataLength, const u16 addr,
} }
} }
bool SerialPort::openSp() { bool SerialPort::openSp()
{
logde << "openSp 1"; logde << "openSp 1";
closeSp(); closeSp();
QThread::msleep(100); QThread::msleep(100);
@ -379,17 +457,20 @@ bool SerialPort::openSp() {
#endif #endif
logde << "openSp 2"; logde << "openSp 2";
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) { foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
{
u16 pid = info.productIdentifier(); u16 pid = info.productIdentifier();
u16 vid = info.vendorIdentifier(); u16 vid = info.vendorIdentifier();
if ((pid == conPid) && (vid == conVid)) { if ((pid == conPid) && (vid == conVid))
{
_sp->setPort(info); _sp->setPort(info);
break; break;
} }
} }
logde << "openSp 3"; logde << "openSp 3";
if (_sp == nullptr) { if (_sp == nullptr)
{
qDebug() << "Device not found."; qDebug() << "Device not found.";
return false; return false;
} }
@ -408,10 +489,13 @@ bool SerialPort::openSp() {
logde << "openSp 4"; logde << "openSp 4";
// 2.打开串口 // 2.打开串口
if (!_sp->open(QIODevice::ReadWrite)) { if (!_sp->open(QIODevice::ReadWrite))
{
qDebug() << "open failed." << _sp->error(); qDebug() << "open failed." << _sp->error();
return false; return false;
} else { }
else
{
// qDebug() << "open succ."; // qDebug() << "open succ.";
logde << "openSp 5."; logde << "openSp 5.";
// 设置 DTR 信号为就绪状态true 表示低电平) // 设置 DTR 信号为就绪状态true 表示低电平)
@ -422,29 +506,37 @@ bool SerialPort::openSp() {
return true; return true;
} }
bool SerialPort::closeSp() { bool SerialPort::closeSp()
if (_sp && _sp->isOpen()) { {
if (_sp && _sp->isOpen())
{
_sp->clear(); _sp->clear();
_sp->close(); _sp->close();
} }
} }
void SerialPort::sendCmd(const SerialPort::E_CMD_TYPE e) { void SerialPort::sendCmd(const SerialPort::E_CMD_TYPE e)
{
#if 1 #if 1
int length = 20; int length = 20;
char in_char[21] = {'\0'}; char in_char[21] = {'\0'};
if (e == e_zero) { if (e == e_zero)
{
// char data[10] = {'55','aa','0b','0a','20', // char data[10] = {'55','aa','0b','0a','20',
// '4e','00','00','00','c3'}; // '4e','00','00','00','c3'};
const char *data = "55aa0b0a204e000000c3"; const char *data = "55aa0b0a204e000000c3";
memcpy(in_char, data, length); memcpy(in_char, data, length);
} else if (e == e_back) { }
else if (e == e_back)
{
// char data[10] = {'55','aa','08','10','27', // char data[10] = {'55','aa','08','10','27',
// 'f0','d8','ff','ff','c3'}; // 'f0','d8','ff','ff','c3'};
const char *data = "55aa081027f0d8ffffc3"; const char *data = "55aa081027f0d8ffffc3";
memcpy(in_char, data, length); memcpy(in_char, data, length);
} else if (e == e_forward) { }
else if (e == e_forward)
{
// char data[10] = {'55','aa','08','10','27', // char data[10] = {'55','aa','08','10','27',
// '10','27','00','00','c3'}; // '10','27','00','00','c3'};
const char *data = "55aa08102710270000c3"; const char *data = "55aa08102710270000c3";
@ -460,15 +552,20 @@ void SerialPort::sendCmd(const SerialPort::E_CMD_TYPE e) {
int num = _sp->write(out_char, int num = _sp->write(out_char,
hex_length); hex_length);
if (num == -1) { if (num == -1)
{
qDebug() << "write failed."; qDebug() << "write failed.";
} else { }
else
{
qDebug() << "write ok|num:" << num; qDebug() << "write ok|num:" << num;
} }
} }
void SerialPort::toHex(char *in_char, int char_length, char *out_char) { void SerialPort::toHex(char *in_char, int char_length, char *out_char)
while (char_length--) { {
while (char_length--)
{
*out_char = (*in_char & 0x40 ? *in_char + 9 : *in_char) << 4; *out_char = (*in_char & 0x40 ? *in_char + 9 : *in_char) << 4;
++in_char; ++in_char;
*out_char |= (*in_char & 0x40 ? *in_char + 9 : *in_char) & 0xF; *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(); QList<QSerialPortInfo> serialPorts = QSerialPortInfo::availablePorts();
// 遍历每个串口信息 // 遍历每个串口信息
for (const QSerialPortInfo &portInfo : serialPorts) { for (const QSerialPortInfo &portInfo : serialPorts)
{
qDebug() << "================================================"; qDebug() << "================================================";
// 打印串口的名称 // 打印串口的名称
qDebug() << "串口名称: " << portInfo.portName(); qDebug() << "串口名称: " << portInfo.portName();
@ -499,14 +598,16 @@ void SerialPort::displayPortInfo() {
// 打印是否有产品标识符 // 打印是否有产品标识符
qDebug() << "是否有产品标识符: " << (portInfo.hasProductIdentifier() ? "" : ""); qDebug() << "是否有产品标识符: " << (portInfo.hasProductIdentifier() ? "" : "");
// 如果有虚拟调制解调器,打印其标识符 // 如果有虚拟调制解调器,打印其标识符
if (portInfo.hasVendorIdentifier()) { if (portInfo.hasVendorIdentifier())
{
qint16 vid = portInfo.vendorIdentifier(); qint16 vid = portInfo.vendorIdentifier();
qDebug() << "虚拟调制解调器标识符: " << vid; qDebug() << "虚拟调制解调器标识符: " << vid;
QString hexStr = QString("0x%1").arg(vid, 4, 16, QChar('0')).toUpper(); QString hexStr = QString("0x%1").arg(vid, 4, 16, QChar('0')).toUpper();
qDebug() << "vid 0x" << hexStr; qDebug() << "vid 0x" << hexStr;
} }
// 如果有产品标识符,打印其标识符 // 如果有产品标识符,打印其标识符
if (portInfo.hasProductIdentifier()) { if (portInfo.hasProductIdentifier())
{
qint16 pid = portInfo.productIdentifier(); qint16 pid = portInfo.productIdentifier();
qDebug() << "产品标识符: " << pid; qDebug() << "产品标识符: " << pid;
QString hexStr = QString("0x%1").arg(pid, 4, 16, QChar('0')).toUpper(); QString hexStr = QString("0x%1").arg(pid, 4, 16, QChar('0')).toUpper();
@ -515,24 +616,29 @@ void SerialPort::displayPortInfo() {
} }
} }
void SerialPort::updateAxis() { void SerialPort::updateAxis()
{
static Global::Mode previousMode = Global::Analysis; // 记录上一次的模式 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; // std::cout << "Mode has changed from Analysis to Experiment!" << std::endl;
Global::ExperimentInfo &eti = Global::_experimentInfo; Global::ExperimentInfo &eti = Global::_experimentInfo;
if (eti.phaseVtr.size() > 0) { if (eti.phaseVtr.size() > 0)
{
logde << "serialport set axis."; logde << "serialport set axis.";
float temp = eti.phaseVtr.at(0).cutoff_temp; 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; previousMode = Global::_mode;
} }
} }
void SerialPort::parserTest() { void SerialPort::parserTest()
{
const uchar data[] = {0xa5, 0x5a, 0x2d, 0x83, const uchar data[] = {0xa5, 0x5a, 0x2d, 0x83,
0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x23, 0x23, 0x00, 0x01, 0x23, 0x23,
@ -572,12 +678,14 @@ void SerialPort::parserTest() {
#endif #endif
} }
void SerialPort::slotDeliverData(const QByteArray &ba) { void SerialPort::slotDeliverData(const QByteArray &ba)
{
openSp(); openSp();
slotSendData(ba); slotSendData(ba);
} }
void SerialPort::slotSendData(const QByteArray &ba) { void SerialPort::slotSendData(const QByteArray &ba)
{
#if 1 #if 1
logde << "slotSendData =========================="; logde << "slotSendData ==========================";
logde << "slotSendData:" << ba.size(); logde << "slotSendData:" << ba.size();
@ -585,35 +693,48 @@ void SerialPort::slotSendData(const QByteArray &ba) {
logde << "slotSendData:" << hexData.toStdString(); logde << "slotSendData:" << hexData.toStdString();
#endif #endif
if (_sp != nullptr && _sp->isOpen()) { if (_sp != nullptr && _sp->isOpen())
{
int bytesWritten = _sp->write(ba); int bytesWritten = _sp->write(ba);
if (bytesWritten == -1) { if (bytesWritten == -1)
{
logde << "Write failed." << _sp->errorString().toStdString(); logde << "Write failed." << _sp->errorString().toStdString();
} else if (bytesWritten != ba.size()) { }
else if (bytesWritten != ba.size())
{
logde << "Not all data was writen."; logde << "Not all data was writen.";
} else { }
else
{
logde << "All data writen."; logde << "All data writen.";
} }
} else { }
else
{
logde << "sp not open."; logde << "sp not open.";
return; return;
} }
} }
void SerialPort::slotCloseSp() { void SerialPort::slotCloseSp()
if (_sp != nullptr && _sp->isOpen()) { {
if (_sp != nullptr && _sp->isOpen())
{
_sp->close(); _sp->close();
} }
} }
void SerialPort::slotPortCheck() { void SerialPort::slotPortCheck()
{
// logde<<"slotPortCheck..."; // logde<<"slotPortCheck...";
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) { foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
{
u16 pid = info.productIdentifier(); u16 pid = info.productIdentifier();
u16 vid = info.vendorIdentifier(); u16 vid = info.vendorIdentifier();
if ((pid == conPid) && (vid == conVid)) { if ((pid == conPid) && (vid == conVid))
{
// logde<<"slotPortCheck... device connected."; // logde<<"slotPortCheck... device connected.";
return; return;
} }

View File

@ -10,7 +10,8 @@
#include "filemanager.h" #include "filemanager.h"
#include "logger.h" #include "logger.h"
QString extractObjectName(const QString &fullObjectName) { QString extractObjectName(const QString &fullObjectName)
{
return fullObjectName.mid(4); // 去掉前 4 个字符("ui->" return fullObjectName.mid(4); // 去掉前 4 个字符("ui->"
} }
@ -18,7 +19,8 @@ QString extractObjectName(const QString &fullObjectName) {
WIDGET->setObjectName(extractObjectName(#WIDGET)) WIDGET->setObjectName(extractObjectName(#WIDGET))
ExperimentSettingForm::ExperimentSettingForm(QWidget *parent) : QWidget(parent), ExperimentSettingForm::ExperimentSettingForm(QWidget *parent) : QWidget(parent),
ui(new Ui::ExperimentSettingForm) { ui(new Ui::ExperimentSettingForm)
{
ui->setupUi(this); ui->setupUi(this);
ui->sampleNameLineEdit->setText("new"); ui->sampleNameLineEdit->setText("new");
@ -52,11 +54,13 @@ ExperimentSettingForm::ExperimentSettingForm(QWidget *parent) : QWidget(parent),
this, &ExperimentSettingForm::slotCancel); this, &ExperimentSettingForm::slotCancel);
} }
ExperimentSettingForm::~ExperimentSettingForm() { ExperimentSettingForm::~ExperimentSettingForm()
{
delete ui; delete ui;
} }
void ExperimentSettingForm::uiReset() { void ExperimentSettingForm::uiReset()
{
// init data and status. // init data and status.
// default value // default value
@ -164,8 +168,10 @@ void ExperimentSettingForm::uiReset() {
SET_OBJECT_NAME(ui->comboBox_initial_atmosphere); SET_OBJECT_NAME(ui->comboBox_initial_atmosphere);
} }
void ExperimentSettingForm::uiSetPhaseEnable(const int index) { void ExperimentSettingForm::uiSetPhaseEnable(const int index)
switch (index) { {
switch (index)
{
case 1: case 1:
ui->checkBox_phase_1->setTristate(true); ui->checkBox_phase_1->setTristate(true);
ui->phase_1_cutoff_temp->setEnabled(true); ui->phase_1_cutoff_temp->setEnabled(true);
@ -213,8 +219,10 @@ void ExperimentSettingForm::uiSetPhaseEnable(const int index) {
} }
} }
GasType ExperimentSettingForm::conver2GasType(const int index) { GasType ExperimentSettingForm::conver2GasType(const int index)
switch (index) { {
switch (index)
{
case 0: case 0:
return GasType::NC; return GasType::NC;
break; // 假设 GAS_AIR 是 gas_type 的枚举值 break; // 假设 GAS_AIR 是 gas_type 的枚举值
@ -234,14 +242,16 @@ GasType ExperimentSettingForm::conver2GasType(const int index) {
bool ExperimentSettingForm::phaseCufoffTempAndTempFlowCheck(const int phaseIndex, bool ExperimentSettingForm::phaseCufoffTempAndTempFlowCheck(const int phaseIndex,
const float prePhaseCufoffTemp, const float prePhaseCufoffTemp,
const float currentPhaseCufoffTemp, const float currentPhaseCufoffTemp,
const float tempFlow) { const float tempFlow)
if (tempFlow < 0) { {
if (tempFlow < 0)
{
phaseScanRateErrorMesgBox(phaseIndex); phaseScanRateErrorMesgBox(phaseIndex);
return false; return false;
} }
if (prePhaseCufoffTemp != currentPhaseCufoffTemp if (prePhaseCufoffTemp != currentPhaseCufoffTemp && tempFlow == 0)
&& tempFlow == 0) { {
phaseScanRateErrorMesgBox(phaseIndex); phaseScanRateErrorMesgBox(phaseIndex);
return false; return false;
} }
@ -249,19 +259,26 @@ bool ExperimentSettingForm::phaseCufoffTempAndTempFlowCheck(const int phaseInd
return true; return true;
} }
void ExperimentSettingForm::slotPhase2StateChanged(int state) { void ExperimentSettingForm::slotPhase2StateChanged(int state)
{
qDebug() << "slotPhase2StateChanged:" << state; qDebug() << "slotPhase2StateChanged:" << state;
if (state == Qt::PartiallyChecked) { if (state == Qt::PartiallyChecked)
{
ui->phase_2_cutoff_temp->setEnabled(true); ui->phase_2_cutoff_temp->setEnabled(true);
ui->phase_2_scan_rate->setEnabled(true); ui->phase_2_scan_rate->setEnabled(true);
ui->phase_2_constant_temp->setEnabled(true); ui->phase_2_constant_temp->setEnabled(true);
ui->comboBox_phase_2_atmosphere->setEnabled(true); ui->comboBox_phase_2_atmosphere->setEnabled(true);
} else { }
else
{
// unchecked // unchecked
if (ui->checkBox_phase_3->isChecked()) { if (ui->checkBox_phase_3->isChecked())
{
ui->checkBox_phase_2->setChecked(true); ui->checkBox_phase_2->setChecked(true);
} else { }
else
{
ui->phase_2_cutoff_temp->setEnabled(false); ui->phase_2_cutoff_temp->setEnabled(false);
ui->phase_2_scan_rate->setEnabled(false); ui->phase_2_scan_rate->setEnabled(false);
ui->phase_2_constant_temp->setEnabled(false); ui->phase_2_constant_temp->setEnabled(false);
@ -270,20 +287,30 @@ void ExperimentSettingForm::slotPhase2StateChanged(int state) {
} }
} }
void ExperimentSettingForm::slotPhase3StateChanged(int state) { void ExperimentSettingForm::slotPhase3StateChanged(int state)
if (state == Qt::PartiallyChecked) { {
if (ui->checkBox_phase_2->isChecked()) { if (state == Qt::PartiallyChecked)
{
if (ui->checkBox_phase_2->isChecked())
{
ui->phase_3_cutoff_temp->setEnabled(true); ui->phase_3_cutoff_temp->setEnabled(true);
ui->phase_3_scan_rate->setEnabled(true); ui->phase_3_scan_rate->setEnabled(true);
ui->phase_3_constant_temp->setEnabled(true); ui->phase_3_constant_temp->setEnabled(true);
ui->comboBox_phase_3_atmosphere->setEnabled(true); ui->comboBox_phase_3_atmosphere->setEnabled(true);
} else { }
else
{
ui->checkBox_phase_3->setChecked(false); 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); ui->checkBox_phase_3->setChecked(true);
} else { }
else
{
ui->phase_3_cutoff_temp->setEnabled(false); ui->phase_3_cutoff_temp->setEnabled(false);
ui->phase_3_scan_rate->setEnabled(false); ui->phase_3_scan_rate->setEnabled(false);
ui->phase_3_constant_temp->setEnabled(false); ui->phase_3_constant_temp->setEnabled(false);
@ -292,20 +319,30 @@ void ExperimentSettingForm::slotPhase3StateChanged(int state) {
} }
} }
void ExperimentSettingForm::slotPhase4StateChanged(int state) { void ExperimentSettingForm::slotPhase4StateChanged(int state)
if (state == Qt::PartiallyChecked) { {
if (ui->checkBox_phase_3->isChecked()) { if (state == Qt::PartiallyChecked)
{
if (ui->checkBox_phase_3->isChecked())
{
ui->phase_4_cutoff_temp->setEnabled(true); ui->phase_4_cutoff_temp->setEnabled(true);
ui->phase_4_scan_rate->setEnabled(true); ui->phase_4_scan_rate->setEnabled(true);
ui->phase_4_constant_temp->setEnabled(true); ui->phase_4_constant_temp->setEnabled(true);
ui->comboBox_phase_4_atmosphere->setEnabled(true); ui->comboBox_phase_4_atmosphere->setEnabled(true);
} else { }
else
{
ui->checkBox_phase_4->setChecked(false); 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); ui->checkBox_phase_4->setChecked(true);
} else { }
else
{
ui->phase_4_cutoff_temp->setEnabled(false); ui->phase_4_cutoff_temp->setEnabled(false);
ui->phase_4_scan_rate->setEnabled(false); ui->phase_4_scan_rate->setEnabled(false);
ui->phase_4_constant_temp->setEnabled(false); ui->phase_4_constant_temp->setEnabled(false);
@ -314,20 +351,30 @@ void ExperimentSettingForm::slotPhase4StateChanged(int state) {
} }
} }
void ExperimentSettingForm::slotPhase5StateChanged(int state) { void ExperimentSettingForm::slotPhase5StateChanged(int state)
if (state == Qt::PartiallyChecked) { {
if (ui->checkBox_phase_4->isChecked()) { if (state == Qt::PartiallyChecked)
{
if (ui->checkBox_phase_4->isChecked())
{
ui->phase_5_cutoff_temp->setEnabled(true); ui->phase_5_cutoff_temp->setEnabled(true);
ui->phase_5_scan_rate->setEnabled(true); ui->phase_5_scan_rate->setEnabled(true);
ui->phase_5_constant_temp->setEnabled(true); ui->phase_5_constant_temp->setEnabled(true);
ui->comboBox_phase_5_atmosphere->setEnabled(true); ui->comboBox_phase_5_atmosphere->setEnabled(true);
} else { }
else
{
ui->checkBox_phase_5->setChecked(false); 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); ui->checkBox_phase_5->setChecked(true);
} else { }
else
{
ui->phase_5_cutoff_temp->setEnabled(false); ui->phase_5_cutoff_temp->setEnabled(false);
ui->phase_5_scan_rate->setEnabled(false); ui->phase_5_scan_rate->setEnabled(false);
ui->phase_5_constant_temp->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; qDebug() << "slotPhase2StateChanged:" << state;
if (state == Qt::PartiallyChecked) { if (state == Qt::PartiallyChecked)
if (ui->checkBox_phase_5->isChecked()) { {
if (ui->checkBox_phase_5->isChecked())
{
ui->phase_6_cutoff_temp->setEnabled(true); ui->phase_6_cutoff_temp->setEnabled(true);
ui->phase_6_scan_rate->setEnabled(true); ui->phase_6_scan_rate->setEnabled(true);
ui->phase_6_constant_temp->setEnabled(true); ui->phase_6_constant_temp->setEnabled(true);
ui->comboBox_phase_6_atmosphere->setEnabled(true); ui->comboBox_phase_6_atmosphere->setEnabled(true);
} else { }
else
{
ui->checkBox_phase_6->setChecked(false); ui->checkBox_phase_6->setChecked(false);
} }
} else { }
else
{
ui->phase_6_cutoff_temp->setEnabled(false); ui->phase_6_cutoff_temp->setEnabled(false);
ui->phase_6_scan_rate->setEnabled(false); ui->phase_6_scan_rate->setEnabled(false);
ui->phase_6_constant_temp->setEnabled(false); ui->phase_6_constant_temp->setEnabled(false);
ui->comboBox_phase_6_atmosphere->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 phase1CutoffTemp = 0.0;
float phase2CutoffTemp = 0.0; float phase2CutoffTemp = 0.0;
float phase3CutoffTemp = 0.0; float phase3CutoffTemp = 0.0;
@ -378,7 +433,8 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
// //
phase1CutoffTemp = phase.cutoff_temp; phase1CutoffTemp = phase.cutoff_temp;
// //
if (phase.temp_flow <= 0) { if (phase.temp_flow <= 0)
{
phaseScanRateErrorMesgBox(1); phaseScanRateErrorMesgBox(1);
return; return;
} }
@ -394,10 +450,12 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
phaseVtr.push_back(phase); phaseVtr.push_back(phase);
// //
if (phase.onoff) { if (phase.onoff)
{
logde << "phase 2 enable."; logde << "phase 2 enable.";
phase2CutoffTemp = phase.cutoff_temp; phase2CutoffTemp = phase.cutoff_temp;
if (phase2CutoffTemp < phase1CutoffTemp) { if (phase2CutoffTemp < phase1CutoffTemp)
{
phaseCufoffTempErrorMesgBox(2); phaseCufoffTempErrorMesgBox(2);
return; return;
} }
@ -418,7 +476,8 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
if (!phaseCufoffTempAndTempFlowCheck(2, if (!phaseCufoffTempAndTempFlowCheck(2,
phase1CutoffTemp, phase1CutoffTemp,
phase2CutoffTemp, phase2CutoffTemp,
phase.temp_flow)) { phase.temp_flow))
{
return; return;
} }
} }
@ -434,10 +493,12 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
phaseVtr.push_back(phase); phaseVtr.push_back(phase);
// //
if (phase.onoff) { if (phase.onoff)
{
logde << "phase 3 enable."; logde << "phase 3 enable.";
phase3CutoffTemp = phase.cutoff_temp; phase3CutoffTemp = phase.cutoff_temp;
if (phase3CutoffTemp < phase2CutoffTemp) { if (phase3CutoffTemp < phase2CutoffTemp)
{
phaseCufoffTempErrorMesgBox(3); phaseCufoffTempErrorMesgBox(3);
return; return;
} }
@ -450,7 +511,8 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
if (!phaseCufoffTempAndTempFlowCheck(3, if (!phaseCufoffTempAndTempFlowCheck(3,
phase2CutoffTemp, phase2CutoffTemp,
phase3CutoffTemp, phase3CutoffTemp,
phase.temp_flow)) { phase.temp_flow))
{
return; return;
} }
} }
@ -466,10 +528,12 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
phaseVtr.push_back(phase); phaseVtr.push_back(phase);
// //
if (phase.onoff) { if (phase.onoff)
{
logde << "phase 4 enable."; logde << "phase 4 enable.";
phase4CutoffTemp = phase.cutoff_temp; phase4CutoffTemp = phase.cutoff_temp;
if (phase4CutoffTemp < phase3CutoffTemp) { if (phase4CutoffTemp < phase3CutoffTemp)
{
phaseCufoffTempErrorMesgBox(4); phaseCufoffTempErrorMesgBox(4);
return; return;
} }
@ -482,7 +546,8 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
if (!phaseCufoffTempAndTempFlowCheck(4, if (!phaseCufoffTempAndTempFlowCheck(4,
phase3CutoffTemp, phase3CutoffTemp,
phase4CutoffTemp, phase4CutoffTemp,
phase.temp_flow)) { phase.temp_flow))
{
return; return;
} }
} }
@ -498,10 +563,12 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
phaseVtr.push_back(phase); phaseVtr.push_back(phase);
// //
if (phase.onoff) { if (phase.onoff)
{
logde << "phase 5 enable."; logde << "phase 5 enable.";
phase5CutoffTemp = phase.cutoff_temp; phase5CutoffTemp = phase.cutoff_temp;
if (phase5CutoffTemp < phase4CutoffTemp) { if (phase5CutoffTemp < phase4CutoffTemp)
{
phaseCufoffTempErrorMesgBox(5); phaseCufoffTempErrorMesgBox(5);
return; return;
} }
@ -514,7 +581,8 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
if (!phaseCufoffTempAndTempFlowCheck(5, if (!phaseCufoffTempAndTempFlowCheck(5,
phase4CutoffTemp, phase4CutoffTemp,
phase5CutoffTemp, phase5CutoffTemp,
phase.temp_flow)) { phase.temp_flow))
{
return; return;
} }
} }
@ -530,10 +598,12 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
phaseVtr.push_back(phase); phaseVtr.push_back(phase);
// //
if (phase.onoff) { if (phase.onoff)
{
logde << "phase 6 enable."; logde << "phase 6 enable.";
phase6CutoffTemp = phase.cutoff_temp; phase6CutoffTemp = phase.cutoff_temp;
if (phase6CutoffTemp < phase5CutoffTemp) { if (phase6CutoffTemp < phase5CutoffTemp)
{
phaseCufoffTempErrorMesgBox(6); phaseCufoffTempErrorMesgBox(6);
return; return;
} }
@ -546,7 +616,8 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
if (!phaseCufoffTempAndTempFlowCheck(6, if (!phaseCufoffTempAndTempFlowCheck(6,
phase5CutoffTemp, phase5CutoffTemp,
phase6CutoffTemp, phase6CutoffTemp,
phase.temp_flow)) { phase.temp_flow))
{
return; return;
} }
} }
@ -571,13 +642,16 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
// initial data. // initial data.
QByteArray initialBa; QByteArray initialBa;
if (ui->radioButton_OIT->isChecked()) { if (ui->radioButton_OIT->isChecked())
{
initialBa.append((char)0); initialBa.append((char)0);
Global::_experimentOITFlag = true; Global::_experimentOITFlag = true;
logde << "Global::_experimentOITFlag = true;"; logde << "Global::_experimentOITFlag = true;";
} else { }
else
{
initialBa.append((char)1); initialBa.append((char)1);
Global::_experimentOITFlag = false; Global::_experimentOITFlag = false;
@ -589,7 +663,8 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
initialBa.append(index); initialBa.append(index);
// 实验名称检查 // 实验名称检查
if (Global::isFileExist(ei.sampleName)) { if (Global::isFileExist(ei.sampleName))
{
QMessageBox::question(this, "实验名称重复", "实验名称已存在,请重新输入!", QMessageBox::question(this, "实验名称重复", "实验名称已存在,请重新输入!",
QMessageBox::Yes); QMessageBox::Yes);
return; return;
@ -603,55 +678,73 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
hide(); hide();
} }
void ExperimentSettingForm::slotCancel() { void ExperimentSettingForm::slotCancel()
{
hide(); hide();
} }
void ExperimentSettingForm::phaseCufoffTempErrorMesgBox(const int phaseNum) { void ExperimentSettingForm::phaseCufoffTempErrorMesgBox(const int phaseNum)
{
QString title = QString("阶段%1截止温度错误").arg(QString::number(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::question(this, title, text,
QMessageBox::Yes); QMessageBox::Yes);
} }
void ExperimentSettingForm::phaseScanRateErrorMesgBox(const int phaseNum) { void ExperimentSettingForm::phaseScanRateErrorMesgBox(const int phaseNum)
{
QString title = QString("阶段%1扫描速率错误").arg(QString::number(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::question(this, title, text,
QMessageBox::Yes); QMessageBox::Yes);
} }
void ExperimentSettingForm::slotPhaseCheck() { void ExperimentSettingForm::slotPhaseCheck()
if (sender() == ui->checkBox_phase_2) { {
if (ui->checkBox_phase_2->isChecked()) { if (sender() == ui->checkBox_phase_2)
{
if (ui->checkBox_phase_2->isChecked())
{
ui->phase_2_cutoff_temp->setEnabled(true); ui->phase_2_cutoff_temp->setEnabled(true);
ui->phase_2_scan_rate->setEnabled(true); ui->phase_2_scan_rate->setEnabled(true);
ui->phase_2_constant_temp->setEnabled(true); ui->phase_2_constant_temp->setEnabled(true);
ui->comboBox_phase_2_atmosphere->setEnabled(true); ui->comboBox_phase_2_atmosphere->setEnabled(true);
} else { }
else
{
ui->phase_2_cutoff_temp->setEnabled(false); ui->phase_2_cutoff_temp->setEnabled(false);
ui->phase_2_scan_rate->setEnabled(false); ui->phase_2_scan_rate->setEnabled(false);
ui->phase_2_constant_temp->setEnabled(false); ui->phase_2_constant_temp->setEnabled(false);
ui->comboBox_phase_2_atmosphere->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_cutoff_temp->setEnabled(true);
ui->phase_3_scan_rate->setEnabled(true); ui->phase_3_scan_rate->setEnabled(true);
ui->phase_3_constant_temp->setEnabled(true); ui->phase_3_constant_temp->setEnabled(true);
ui->comboBox_phase_3_atmosphere->setEnabled(true); ui->comboBox_phase_3_atmosphere->setEnabled(true);
} else { }
else
{
ui->phase_3_cutoff_temp->setEnabled(false); ui->phase_3_cutoff_temp->setEnabled(false);
ui->phase_3_scan_rate->setEnabled(false); ui->phase_3_scan_rate->setEnabled(false);
ui->phase_3_constant_temp->setEnabled(false); ui->phase_3_constant_temp->setEnabled(false);
ui->comboBox_phase_3_atmosphere->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_cutoff_temp->setEnabled(true);
ui->phase_4_scan_rate->setEnabled(true); ui->phase_4_scan_rate->setEnabled(true);
ui->phase_4_constant_temp->setEnabled(true); ui->phase_4_constant_temp->setEnabled(true);
ui->comboBox_phase_4_atmosphere->setEnabled(true); ui->comboBox_phase_4_atmosphere->setEnabled(true);
} else { }
else
{
ui->phase_4_cutoff_temp->setEnabled(false); ui->phase_4_cutoff_temp->setEnabled(false);
ui->phase_4_scan_rate->setEnabled(false); ui->phase_4_scan_rate->setEnabled(false);
ui->phase_4_constant_temp->setEnabled(false); ui->phase_4_constant_temp->setEnabled(false);
@ -660,7 +753,8 @@ void ExperimentSettingForm::slotPhaseCheck() {
} }
} }
void ExperimentSettingForm::slotRecvPhaseInfo(const QByteArray &ba) { void ExperimentSettingForm::slotRecvPhaseInfo(const QByteArray &ba)
{
logde << "recv phase info ----------------------- "; logde << "recv phase info ----------------------- ";
#if 1 #if 1
@ -676,7 +770,8 @@ void ExperimentSettingForm::slotRecvPhaseInfo(const QByteArray &ba) {
int phaseSize = spp->len / PHASE_BYTE_SIZE; int phaseSize = spp->len / PHASE_BYTE_SIZE;
QVector<Phase> phaseVtr; QVector<Phase> phaseVtr;
for (int i = 0; i < phaseSize; i++) { for (int i = 0; i < phaseSize; i++)
{
#if 0 #if 0
Phase *phase = (Phase *)(data + i * PHASE_BYTE_SIZE); Phase *phase = (Phase *)(data + i * PHASE_BYTE_SIZE);
phaseVtr.push_back(*phase); phaseVtr.push_back(*phase);
@ -741,7 +836,8 @@ void ExperimentSettingForm::slotRecvPhaseInfo(const QByteArray &ba) {
// 解析 gas // 解析 gas
uint8_t gasType = *(localData + index); uint8_t gasType = *(localData + index);
switch (gasType) { switch (gasType)
{
case NC: case NC:
phase.gas = NC; phase.gas = NC;
break; break;
@ -763,11 +859,15 @@ void ExperimentSettingForm::slotRecvPhaseInfo(const QByteArray &ba) {
// ui update // ui update
// logde<<"phaseVtr size:"<<phaseVtr.size(); // logde<<"phaseVtr size:"<<phaseVtr.size();
// ui重置成默认状态
uiReset(); uiReset();
for (int i = 0; i < phaseVtr.size();) { // ui设置实验阶段参数
for (int i = 0; i < phaseVtr.size();)
{
const Phase &phase = phaseVtr[i]; const Phase &phase = phaseVtr[i];
if (phase.onoff == 0) { if (phase.onoff == 0)
{
break; break;
} }
@ -776,16 +876,20 @@ void ExperimentSettingForm::slotRecvPhaseInfo(const QByteArray &ba) {
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)); QCheckBox *checkBox_phase = qobject_cast<QCheckBox *>(this->findChild<QObject *>(checkBoxName));
if (checkBox_phase) { if (checkBox_phase)
{
checkBox_phase->setChecked(true); checkBox_phase->setChecked(true);
// qDebug()<<"found..."; // qDebug()<<"found...";
} else { }
else
{
// qDebug()<<"not found..."; // qDebug()<<"not found...";
} }
QString cutOffTempLineEditName = QString("phase_%1_cutoff_temp").arg(i); QString cutOffTempLineEditName = QString("phase_%1_cutoff_temp").arg(i);
QLineEdit *cutOffTempLineEdit = qobject_cast<QLineEdit *>(this->findChild<QObject *>(cutOffTempLineEditName)); QLineEdit *cutOffTempLineEdit = qobject_cast<QLineEdit *>(this->findChild<QObject *>(cutOffTempLineEditName));
if (cutOffTempLineEdit) { if (cutOffTempLineEdit)
{
cutOffTempLineEdit->setText(QString::number(phase.cutoff_temp, 'f', 3)); cutOffTempLineEdit->setText(QString::number(phase.cutoff_temp, 'f', 3));
cutOffTempLineEdit->setEnabled(true); cutOffTempLineEdit->setEnabled(true);
} }
@ -793,21 +897,24 @@ void ExperimentSettingForm::slotRecvPhaseInfo(const QByteArray &ba) {
QString scanRateLineEditName = QString("phase_%1_scan_rate").arg(i); QString scanRateLineEditName = QString("phase_%1_scan_rate").arg(i);
QLineEdit *scanRateLineEdit = QLineEdit *scanRateLineEdit =
qobject_cast<QLineEdit *>(this->findChild<QObject *>(scanRateLineEditName)); qobject_cast<QLineEdit *>(this->findChild<QObject *>(scanRateLineEditName));
if (scanRateLineEdit) { if (scanRateLineEdit)
{
scanRateLineEdit->setText(QString::number(phase.temp_flow, 'f', 3)); scanRateLineEdit->setText(QString::number(phase.temp_flow, 'f', 3));
scanRateLineEdit->setEnabled(true); scanRateLineEdit->setEnabled(true);
} }
QString constantTempLineEditName = QString("phase_%1_constant_temp").arg(i); QString constantTempLineEditName = QString("phase_%1_constant_temp").arg(i);
QLineEdit *constantTempLineEdit = QLineEdit *constantTempLineEdit =
qobject_cast<QLineEdit *>(this->findChild<QObject *>(constantTempLineEditName)); qobject_cast<QLineEdit *>(this->findChild<QObject *>(constantTempLineEditName));
if (constantTempLineEdit) { if (constantTempLineEdit)
{
constantTempLineEdit->setText(QString::number(phase.constant_temp_time_min)); constantTempLineEdit->setText(QString::number(phase.constant_temp_time_min));
constantTempLineEdit->setEnabled(true); constantTempLineEdit->setEnabled(true);
} }
QString atmoshpereComboBoxName = QString("comboBox_phase_%1_atmosphere").arg(i); QString atmoshpereComboBoxName = QString("comboBox_phase_%1_atmosphere").arg(i);
QComboBox *atmoshpereComboBox = QComboBox *atmoshpereComboBox =
qobject_cast<QComboBox *>(this->findChild<QObject *>(atmoshpereComboBoxName)); qobject_cast<QComboBox *>(this->findChild<QObject *>(atmoshpereComboBoxName));
if (atmoshpereComboBox) { if (atmoshpereComboBox)
{
atmoshpereComboBox->setCurrentIndex(phase.gas % 256); atmoshpereComboBox->setCurrentIndex(phase.gas % 256);
atmoshpereComboBox->setEnabled(true); atmoshpereComboBox->setEnabled(true);
} }
@ -817,10 +924,13 @@ void ExperimentSettingForm::slotRecvPhaseInfo(const QByteArray &ba) {
// radioButton_OIT // radioButton_OIT
// comboBox_initial_atmosphere // comboBox_initial_atmosphere
// 设置OIT类型
u8 *oitValue = (data + 72); u8 *oitValue = (data + 72);
logde << "oit value:" << (int)*oitValue; logde << "oit value:" << (int)*oitValue;
if (*oitValue) { if (*oitValue)
{
ui->radioButton_OIT->setChecked(false); ui->radioButton_OIT->setChecked(false);
ui->radioButton_OIT_not->setChecked(true); ui->radioButton_OIT_not->setChecked(true);
#if 0 #if 0
@ -831,7 +941,9 @@ void ExperimentSettingForm::slotRecvPhaseInfo(const QByteArray &ba) {
oitRadioButton->setChecked(true); oitRadioButton->setChecked(true);
} }
#endif #endif
} else { }
else
{
ui->radioButton_OIT->setChecked(true); ui->radioButton_OIT->setChecked(true);
ui->radioButton_OIT_not->setChecked(false); ui->radioButton_OIT_not->setChecked(false);
Global::_experimentOITFlag = true; Global::_experimentOITFlag = true;
@ -847,6 +959,7 @@ void ExperimentSettingForm::slotRecvPhaseInfo(const QByteArray &ba) {
#endif #endif
} }
// 设置默认其他类型。
u8 *initAtmosphereValue = (data + 73); u8 *initAtmosphereValue = (data + 73);
logde << "initAtmosphereValue:" << (int)(*initAtmosphereValue); logde << "initAtmosphereValue:" << (int)(*initAtmosphereValue);
ui->comboBox_initial_atmosphere->setCurrentIndex((int)*initAtmosphereValue); ui->comboBox_initial_atmosphere->setCurrentIndex((int)*initAtmosphereValue);
@ -861,9 +974,28 @@ void ExperimentSettingForm::slotRecvPhaseInfo(const QByteArray &ba) {
#endif #endif
} }
void ExperimentSettingForm::showEvent(QShowEvent *event) { void ExperimentSettingForm::showEvent(QShowEvent *event)
{
QDateTime currentDateTime = QDateTime::currentDateTime(); QDateTime currentDateTime = QDateTime::currentDateTime();
QString internationalFormat = currentDateTime.toString("yyyy/MM/dd hh:mm:ss"); QString internationalFormat = currentDateTime.toString("yyyy/MM/dd hh:mm:ss");
ui->dateTimeLineEdit->setText(internationalFormat); 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);
} }

View File

@ -15,7 +15,7 @@
#include "leftwidget.h" #include "leftwidget.h"
#include "filemanager.h" #include "filemanager.h"
#include "global.h" #include "global.h"
#include "logger.h" #include "../logger/logger.h"
LeftWidget::LeftWidget(QWidget *parent) : QDockWidget(parent) LeftWidget::LeftWidget(QWidget *parent) : QDockWidget(parent)
{ {
@ -38,8 +38,13 @@ LeftWidget::LeftWidget(QWidget *parent) : QDockWidget(parent)
_contextMenu = new QMenu(_treeWidget); _contextMenu = new QMenu(_treeWidget);
_deleteFileAction = new QAction("删除文件", this); _deleteFileAction = new QAction("删除文件", this);
_createFolderAction = 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(_deleteFileAction);
_contextMenu->addAction(_createFolderAction); _contextMenu->addAction(_createFolderAction);
_contextMenu->addMenu(_moveToFolderSubMenu); // Add submenu instead of action
_treeWidget->setContextMenuPolicy(Qt::CustomContextMenu); _treeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
@ -50,20 +55,112 @@ LeftWidget::LeftWidget(QWidget *parent) : QDockWidget(parent)
this, &LeftWidget::slotDeleteActionTriggered); this, &LeftWidget::slotDeleteActionTriggered);
connect(_createFolderAction, &QAction::triggered, connect(_createFolderAction, &QAction::triggered,
this, &LeftWidget::slotCreateFolderActionTriggered); 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() void LeftWidget::reloadFileName()
{ {
#if 0
clearAllChildItems(_sampleDataItem); clearAllChildItems(_sampleDataItem);
// clearAllChildItems(_baseLineItem); // clearAllChildItems(_baseLineItem);
clearAllChildItems(_analysisStateItem); clearAllChildItems(_analysisStateItem);
initFileName(_sampleDataItem, Global::SampleDataFloder); initFileName(_sampleDataItem, Global::SampleDataFloder);
#if 0 #if 0
initFileName(_baseLineItem,Global::BaseLineFolder); initFileName(_baseLineItem,Global::BaseLineFolder);
#endif #endif
initFileName(_analysisStateItem, Global::AnalysisStateFolder); initFileName(_analysisStateItem, Global::AnalysisStateFolder);
#endif
reloadFileTree();
// 更新文件列表 // 更新文件列表
Global::updateFileList(); Global::updateFileList();
} }
@ -131,6 +228,7 @@ void LeftWidget::initData()
} }
#endif #endif
} }
void LeftWidget::slotTreeWidgetItemClicked(QTreeWidgetItem *item, int column) void LeftWidget::slotTreeWidgetItemClicked(QTreeWidgetItem *item, int column)
{ {
qDebug() << "item clicked:" << item->text(0) << column; qDebug() << "item clicked:" << item->text(0) << column;
@ -237,44 +335,10 @@ void LeftWidget::recursiveFolderOperation(const QString& folderPath) {
} }
#endif #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() void LeftWidget::slotDeleteActionTriggered()
{ {
if (_deleteFileActionFilePath.isEmpty()) { if (_deleteFileActionFilePath.isEmpty())
{
return; return;
} }
@ -282,7 +346,8 @@ void LeftWidget::slotDeleteActionTriggered()
bool isDir = fileInfo.isDir(); bool isDir = fileInfo.isDir();
// 检查文件/目录是否存在 // 检查文件/目录是否存在
if (!fileInfo.exists()) { if (!fileInfo.exists())
{
QMessageBox::warning(this, tr("警告"), tr("文件/目录不存在!")); QMessageBox::warning(this, tr("警告"), tr("文件/目录不存在!"));
return; return;
} }
@ -293,20 +358,27 @@ void LeftWidget::slotDeleteActionTriggered()
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes | QMessageBox::No,
QMessageBox::No); QMessageBox::No);
if (ret == QMessageBox::Yes) { if (ret == QMessageBox::Yes)
{
bool success; bool success;
if (isDir) { if (isDir)
{
// 删除目录及其内容 // 删除目录及其内容
success = removeDir(_deleteFileActionFilePath); success = removeDir(_deleteFileActionFilePath);
} else { }
else
{
// 删除文件 // 删除文件
success = QFile::remove(_deleteFileActionFilePath); success = QFile::remove(_deleteFileActionFilePath);
} }
if (success) { if (success)
{
// 重新加载文件树 // 重新加载文件树
reloadFileTree(); reloadFileTree();
} else { }
else
{
QMessageBox::critical(this, tr("错误"), tr("删除失败!")); QMessageBox::critical(this, tr("错误"), tr("删除失败!"));
} }
} }
@ -319,15 +391,21 @@ bool LeftWidget::removeDir(const QString &dirPath)
bool result = true; bool result = true;
QDir dir(dirPath); QDir dir(dirPath);
if (dir.exists(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()) { 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()); result = removeDir(info.absoluteFilePath());
} else { }
else
{
result = QFile::remove(info.absoluteFilePath()); result = QFile::remove(info.absoluteFilePath());
} }
if (!result) { if (!result)
{
return result; return result;
} }
} }
@ -339,18 +417,19 @@ bool LeftWidget::removeDir(const QString &dirPath)
void LeftWidget::slotCreateFolderActionTriggered() void LeftWidget::slotCreateFolderActionTriggered()
{ {
// 获取当前选中的项目 // 创建主分支下的文件夹
QTreeWidgetItem *currentItem = _treeWidget->currentItem(); QTreeWidgetItem *currentItem = _treeWidget->topLevelItem(0);
if (!currentItem) { logde << "currentItem : " << currentItem->text(0).toStdString();
return;
}
// 获取当前目录路径 // 获取当前目录路径
QString dirPath; 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(); dirPath = QFileInfo(currentItem->data(0, Qt::UserRole).toString()).absolutePath();
} else { }
else
{
// 如果是目录,直接使用其路径 // 如果是目录,直接使用其路径
dirPath = currentItem->data(0, Qt::UserRole + 1).toString(); dirPath = currentItem->data(0, Qt::UserRole + 1).toString();
} }
@ -362,12 +441,14 @@ void LeftWidget::slotCreateFolderActionTriggered()
QLineEdit::Normal, QLineEdit::Normal,
tr("新建文件夹"), &ok); tr("新建文件夹"), &ok);
if (!ok || folderName.isEmpty()) { if (!ok || folderName.isEmpty())
{
return; return;
} }
// 检查文件夹名称是否有效 // 检查文件夹名称是否有效
if (folderName.contains(QRegExp("[\\/:*?\"<>|]"))) { if (folderName.contains(QRegExp("[\\/:*?\"<>|]")))
{
QMessageBox::warning(this, tr("错误"), tr("文件夹名称包含非法字符!")); QMessageBox::warning(this, tr("错误"), tr("文件夹名称包含非法字符!"));
return; return;
} }
@ -376,13 +457,15 @@ void LeftWidget::slotCreateFolderActionTriggered()
QString newFolderPath = dirPath + "/" + folderName; QString newFolderPath = dirPath + "/" + folderName;
// 检查文件夹是否已存在 // 检查文件夹是否已存在
if (QDir(newFolderPath).exists()) { if (QDir(newFolderPath).exists())
{
QMessageBox::warning(this, tr("错误"), tr("文件夹已存在!")); QMessageBox::warning(this, tr("错误"), tr("文件夹已存在!"));
return; return;
} }
// 创建文件夹 // 创建文件夹
if (QDir().mkdir(newFolderPath)) { if (QDir().mkdir(newFolderPath))
{
// 保存当前展开状态 // 保存当前展开状态
saveExpandedState(); saveExpandedState();
@ -394,7 +477,9 @@ void LeftWidget::slotCreateFolderActionTriggered()
// 展开当前目录并选中新创建的文件夹 // 展开当前目录并选中新创建的文件夹
expandAndSelectItem(newFolderPath); expandAndSelectItem(newFolderPath);
} else { }
else
{
QMessageBox::critical(this, tr("错误"), tr("创建文件夹失败!")); QMessageBox::critical(this, tr("错误"), tr("创建文件夹失败!"));
} }
} }
@ -403,14 +488,17 @@ void LeftWidget::expandAndSelectItem(const QString &path)
{ {
// 递归展开到指定路径并选中该项 // 递归展开到指定路径并选中该项
QTreeWidgetItemIterator it(_treeWidget); QTreeWidgetItemIterator it(_treeWidget);
while (*it) { while (*it)
{
QTreeWidgetItem *item = *it; QTreeWidgetItem *item = *it;
QString itemPath = item->data(0, Qt::UserRole + 1).toString(); QString itemPath = item->data(0, Qt::UserRole + 1).toString();
if (itemPath == path) { if (itemPath == path)
{
// 展开所有父节点 // 展开所有父节点
QTreeWidgetItem *parent = item->parent(); QTreeWidgetItem *parent = item->parent();
while (parent) { while (parent)
{
parent->setExpanded(true); parent->setExpanded(true);
parent = parent->parent(); parent = parent->parent();
} }
@ -453,7 +541,7 @@ void LeftWidget::reloadFileTree()
// 创建根节点 // 创建根节点
QTreeWidgetItem *rootItem = new QTreeWidgetItem(_treeWidget); QTreeWidgetItem *rootItem = new QTreeWidgetItem(_treeWidget);
rootItem->setText(0, "实验数据"); 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); rootItem->setData(0, Qt::UserRole + 1, Global::ExperimentDirPath);
@ -487,7 +575,8 @@ QFileInfoList LeftWidget::scanDirRecursively(const QString &rootPath)
void LeftWidget::buildFileTree(QTreeWidgetItem *parentItem, const QString &dirPath) void LeftWidget::buildFileTree(QTreeWidgetItem *parentItem, const QString &dirPath)
{ {
QDir dir(dirPath); QDir dir(dirPath);
if (!dir.exists()) { if (!dir.exists())
{
qWarning() << "目录不存在: " << dirPath; qWarning() << "目录不存在: " << dirPath;
return; return;
} }
@ -496,10 +585,12 @@ void LeftWidget::buildFileTree(QTreeWidgetItem *parentItem, const QString &dirPa
dir.setSorting(QDir::Name | QDir::DirsFirst); dir.setSorting(QDir::Name | QDir::DirsFirst);
QFileInfoList list = dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot); 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); QTreeWidgetItem *item = new QTreeWidgetItem(parentItem);
if (fileInfo.isDir()) { if (fileInfo.isDir())
{
// 设置目录项 // 设置目录项
item->setText(0, fileInfo.fileName()); item->setText(0, fileInfo.fileName());
// 使用系统默认的目录图标 // 使用系统默认的目录图标
@ -509,17 +600,22 @@ void LeftWidget::buildFileTree(QTreeWidgetItem *parentItem, const QString &dirPa
// 递归处理子目录 // 递归处理子目录
buildFileTree(item, fileInfo.absoluteFilePath()); buildFileTree(item, fileInfo.absoluteFilePath());
} else { }
else
{
// 设置文件项 // 设置文件项
item->setText(0, fileInfo.fileName()); item->setText(0, fileInfo.fileName());
item->setData(0, Qt::UserRole, fileInfo.absoluteFilePath()); item->setData(0, Qt::UserRole, fileInfo.absoluteFilePath());
// 根据文件类型设置不同的图标 // 根据文件类型设置不同的图标
QString suffix = fileInfo.suffix().toLower(); QString suffix = fileInfo.suffix().toLower();
if (suffix == "xlsx" || suffix == "xls") { if (suffix == "xlsx" || suffix == "xls")
{
// 使用系统默认的文档图标 // 使用系统默认的文档图标
item->setIcon(0, _treeWidget->style()->standardIcon(QStyle::SP_FileIcon)); item->setIcon(0, _treeWidget->style()->standardIcon(QStyle::SP_FileIcon));
} else { }
else
{
// 使用默认文件图标 // 使用默认文件图标
item->setIcon(0, _treeWidget->style()->standardIcon(QStyle::SP_FileIcon)); item->setIcon(0, _treeWidget->style()->standardIcon(QStyle::SP_FileIcon));
} }
@ -533,11 +629,14 @@ void LeftWidget::saveExpandedState()
// 递归遍历所有项,保存展开的目录路径 // 递归遍历所有项,保存展开的目录路径
QTreeWidgetItemIterator it(_treeWidget); QTreeWidgetItemIterator it(_treeWidget);
while (*it) { while (*it)
{
QTreeWidgetItem *item = *it; QTreeWidgetItem *item = *it;
if (item->isExpanded()) { if (item->isExpanded())
{
QVariant pathData = item->data(0, Qt::UserRole + 1); QVariant pathData = item->data(0, Qt::UserRole + 1);
if (!pathData.isNull()) { if (!pathData.isNull())
{
_expandedPaths.append(pathData.toString()); _expandedPaths.append(pathData.toString());
} }
} }
@ -553,12 +652,15 @@ void LeftWidget::restoreExpandedState()
// 递归遍历所有项,恢复展开状态 // 递归遍历所有项,恢复展开状态
QTreeWidgetItemIterator it(_treeWidget); QTreeWidgetItemIterator it(_treeWidget);
while (*it) { while (*it)
{
QTreeWidgetItem *item = *it; QTreeWidgetItem *item = *it;
QVariant pathData = item->data(0, Qt::UserRole + 1); QVariant pathData = item->data(0, Qt::UserRole + 1);
if (!pathData.isNull()) { if (!pathData.isNull())
{
QString path = pathData.toString(); QString path = pathData.toString();
if (_expandedPaths.contains(path)) { if (_expandedPaths.contains(path))
{
item->setExpanded(true); item->setExpanded(true);
restoredCount++; restoredCount++;
} }
@ -568,3 +670,135 @@ void LeftWidget::restoreExpandedState()
qDebug() << "恢复了" << restoredCount << "个展开状态"; 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;
}

View File

@ -22,11 +22,13 @@ public:
void reloadFileTree(); void reloadFileTree();
QString filePathCheck(const QString fileName, const QString folderPath); QString filePathCheck(const QString fileName, const QString folderPath);
// 确认删除文件 // 确认删除文件
void confirmDelete(bool enabled); void confirmDelete(bool enabled);
signals: signals:
void sigSendAnalysisFileName(const QString &); void sigSendAnalysisFileName(const QString &);
void sigDeleteActionTriggered(const QString &); void sigDeleteActionTriggered(const QString &);
private: private:
void initData(); void initData();
void initFileName(QTreeWidgetItem *, const QString &folderPath); void initFileName(QTreeWidgetItem *, const QString &folderPath);
@ -38,22 +40,33 @@ private:
void restoreExpandedState(); void restoreExpandedState();
void expandAndSelectItem(const QString &path); void expandAndSelectItem(const QString &path);
bool removeDir(const QString &dirPath); 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: private slots:
void slotTreeWidgetItemClicked(QTreeWidgetItem *item, int column); void slotTreeWidgetItemClicked(QTreeWidgetItem *item, int column);
// 右键菜单
void slotShowContextMenu(const QPoint &pos); void slotShowContextMenu(const QPoint &pos);
void slotDeleteActionTriggered(); void slotDeleteActionTriggered();
void slotCreateFolderActionTriggered(); void slotCreateFolderActionTriggered();
void slotMoveToFolderActionTriggered(); // Add slot for move to folder action
void slotMoveToSpecificFolder(const QString &targetFolderPath); // 新增:移动到指定文件夹的槽函数
private: private:
QTreeWidget *_treeWidget; QTreeWidget *_treeWidget;
#if 0
QTreeWidgetItem *_analysisStateItem, QTreeWidgetItem *_analysisStateItem,
*_baseLineItem, *_baseLineItem,
*_sampleDataItem; *_sampleDataItem;
#endif
QMenu *_contextMenu; QMenu *_contextMenu;
QAction *_deleteFileAction; QAction *_deleteFileAction;
QAction *_createFolderAction; QAction *_createFolderAction;
QAction *_moveToFolderAction;
QMenu *_moveToFolderSubMenu; // Add submenu for move to folder
QString _deleteFileActionFilePath; QString _deleteFileActionFilePath;
// 保存展开状态的列表 // 保存展开状态的列表
@ -61,4 +74,3 @@ private:
}; };
#endif // LEFTWIDGET_H #endif // LEFTWIDGET_H

View File

@ -84,7 +84,6 @@ void PrintPreviewForm::slotPaintRequested(QPrinter *printer) {
painter.setOpacity(1.0); painter.setOpacity(1.0);
#endif #endif
// 获取页面矩形区域 // 获取页面矩形区域
QRect pageRect = printer->pageRect(); QRect pageRect = printer->pageRect();