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 {
|
||||
@ -180,6 +183,7 @@ extern QString _smoothnessFileName;
|
||||
void updateFileList();
|
||||
bool isFileExist(const QString &fileName);
|
||||
|
||||
|
||||
}; // namespace Global
|
||||
|
||||
#endif // GLOBAL_H
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -37,8 +37,6 @@ bool commonDataParser(const QByteArray &ba, CommonData &cd)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
QByteArray setExperimentInfo(const QVector<Phase> &vtr, const QByteArray initBa)
|
||||
{
|
||||
// const int phaseLength = sizeof(Phase);
|
||||
@ -54,7 +52,6 @@ QByteArray setExperimentInfo(const QVector<Phase> &vtr,const QByteArray initBa)
|
||||
offset += phaseLength;
|
||||
}
|
||||
|
||||
//
|
||||
// int totalDataLength = 0;
|
||||
char totalData[300] = {};
|
||||
|
||||
@ -143,7 +140,8 @@ QByteArray setDeviceStartStop(const DeviceStartMode mode)
|
||||
void experimentalStateSwitching(const CommonData &cd)
|
||||
{
|
||||
// Switch the software mode accord to the serial port data.
|
||||
switch(cd.run_type){
|
||||
switch (cd.run_type)
|
||||
{
|
||||
case DeviceRunStatus::Heat:
|
||||
case DeviceRunStatus::ConstantTemp:
|
||||
Global::_mode = Global::Mode::Experiment;
|
||||
@ -153,7 +151,8 @@ void experimentalStateSwitching(const CommonData &cd)
|
||||
Global::_mode = Global::Mode::Analysis;
|
||||
|
||||
break;
|
||||
default:break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
@ -186,6 +185,7 @@ unsigned short modbusCRC16(unsigned char *data, unsigned short length)
|
||||
return crc;
|
||||
}
|
||||
|
||||
// 请求实验参数
|
||||
QByteArray inquirePhaseInfo()
|
||||
{
|
||||
SerialPortProtocol spp;
|
||||
@ -204,7 +204,4 @@ QByteArray inquirePhaseInfo()
|
||||
QByteArray((char *)&crc, 2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
@ -21,3 +21,8 @@ unsigned short modbusCRC16(unsigned char *data,unsigned short length);
|
||||
}
|
||||
|
||||
#endif // DATAPARSER_H
|
||||
|
||||
/**
|
||||
中油资本
|
||||
孚日股份
|
||||
*/
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#define FRANE_HEAD 0x5AA5 //枕头
|
||||
#define FRANE_HEAD 0x5AA5 //帧头
|
||||
#define WRITE_CMD 0x82 //写指令
|
||||
#define READ_CMD 0x83 //读指令
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
@ -20,7 +20,8 @@ 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);
|
||||
@ -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;
|
||||
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 {
|
||||
}
|
||||
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,16 +187,19 @@ void SerialPort::updateStatus(const CommonData &cd) {
|
||||
#endif
|
||||
|
||||
// Switch the software mode accord to the serial port data.
|
||||
switch (cd.run_type) {
|
||||
switch (cd.run_type)
|
||||
{
|
||||
case DeviceRunStatus::Heat:
|
||||
case DeviceRunStatus::ConstantTemp:
|
||||
if (Global::_mode != Global::Mode::Experiment) {
|
||||
if (Global::_mode != Global::Mode::Experiment)
|
||||
{
|
||||
Global::_mode = Global::Mode::Experiment;
|
||||
}
|
||||
break;
|
||||
case DeviceRunStatus::Idle:
|
||||
case DeviceRunStatus::Cooling:
|
||||
if (Global::_mode != Global::Mode::Analysis) {
|
||||
if (Global::_mode != Global::Mode::Analysis)
|
||||
{
|
||||
Global::_mode = Global::Mode::Analysis;
|
||||
}
|
||||
break;
|
||||
@ -170,12 +210,14 @@ void SerialPort::updateStatus(const CommonData &cd) {
|
||||
// 判断是否根据下位机数据,切换软件实验模式。
|
||||
static Global::Mode preMode = Global::Mode::Analysis;
|
||||
bool sendSaveSignalFlag = false;
|
||||
if (Global::_mode != preMode) {
|
||||
if (preMode == Global::Mode::Experiment
|
||||
&& Global::_mode == Global::Mode::Analysis) {
|
||||
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.";
|
||||
|
||||
@ -217,7 +261,8 @@ void SerialPort::updateStatus(const CommonData &cd) {
|
||||
// Update axis.
|
||||
bool experimentEnded = false;
|
||||
QString devRunModeStr;
|
||||
switch (cd.run_type) {
|
||||
switch (cd.run_type)
|
||||
{
|
||||
case DeviceRunStatus::Heat:
|
||||
devRunModeStr = "升温";
|
||||
experimentEnded = true;
|
||||
@ -237,9 +282,12 @@ void SerialPort::updateStatus(const CommonData &cd) {
|
||||
}
|
||||
|
||||
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,18 +317,26 @@ 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) {
|
||||
const CommonData &cd)
|
||||
{
|
||||
|
||||
int localLength = dataLength;
|
||||
int localAddr = addr;
|
||||
|
||||
logde << "localLength total:" << localLength;
|
||||
logde << "localAddr total:" << localAddr;
|
||||
|
||||
int phaseByteSize = sizeof(Phase);
|
||||
auto phaseParserFunc = [&](const int index) {
|
||||
auto phaseParserFunc = [&](const int index)
|
||||
{
|
||||
Phase phase;
|
||||
phase.onoff = 1;
|
||||
phase.gas = cd.phase_data[index].gas;
|
||||
@ -293,12 +349,17 @@ 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) {
|
||||
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;
|
||||
@ -322,10 +383,12 @@ void SerialPort::commonDataParser(const int dataLength, const u16 addr,
|
||||
localAddr += 4;
|
||||
localLength -= 4;
|
||||
break;
|
||||
case offsetof(CommonData, run_mode): {
|
||||
case offsetof(CommonData, run_mode):
|
||||
{
|
||||
DeviceStartMode mode = (DeviceStartMode)cd.run_mode;
|
||||
|
||||
switch (mode) {
|
||||
switch (mode)
|
||||
{
|
||||
case DeviceStartMode::Stop:
|
||||
Global::_mode = 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):
|
||||
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;
|
||||
@ -367,7 +444,8 @@ void SerialPort::commonDataParser(const int dataLength, const u16 addr,
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@ -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'};
|
||||
|
||||
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";
|
||||
@ -460,15 +552,20 @@ void SerialPort::sendCmd(const SerialPort::E_CMD_TYPE e) {
|
||||
|
||||
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,24 +616,29 @@ void SerialPort::displayPortInfo() {
|
||||
}
|
||||
}
|
||||
|
||||
void SerialPort::updateAxis() {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if (previousMode != Global::_mode) {
|
||||
if (previousMode != Global::_mode)
|
||||
{
|
||||
previousMode = Global::_mode;
|
||||
}
|
||||
}
|
||||
void SerialPort::parserTest() {
|
||||
void SerialPort::parserTest()
|
||||
{
|
||||
const uchar data[] = {0xa5, 0x5a, 0x2d, 0x83,
|
||||
0x00, 0x00,
|
||||
0x00, 0x01, 0x23, 0x23,
|
||||
@ -572,12 +678,14 @@ 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();
|
||||
@ -585,35 +693,48 @@ void SerialPort::slotSendData(const QByteArray &ba) {
|
||||
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() {
|
||||
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)) {
|
||||
if ((pid == conPid) && (vid == conVid))
|
||||
{
|
||||
// logde<<"slotPortCheck... device connected.";
|
||||
return;
|
||||
}
|
||||
|
||||
@ -10,7 +10,8 @@
|
||||
#include "filemanager.h"
|
||||
#include "logger.h"
|
||||
|
||||
QString extractObjectName(const QString &fullObjectName) {
|
||||
QString extractObjectName(const QString &fullObjectName)
|
||||
{
|
||||
return fullObjectName.mid(4); // 去掉前 4 个字符("ui->")
|
||||
}
|
||||
|
||||
@ -18,7 +19,8 @@ QString extractObjectName(const QString &fullObjectName) {
|
||||
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,8 +168,10 @@ void ExperimentSettingForm::uiReset() {
|
||||
SET_OBJECT_NAME(ui->comboBox_initial_atmosphere);
|
||||
}
|
||||
|
||||
void ExperimentSettingForm::uiSetPhaseEnable(const int index) {
|
||||
switch (index) {
|
||||
void ExperimentSettingForm::uiSetPhaseEnable(const int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 1:
|
||||
ui->checkBox_phase_1->setTristate(true);
|
||||
ui->phase_1_cutoff_temp->setEnabled(true);
|
||||
@ -213,8 +219,10 @@ void ExperimentSettingForm::uiSetPhaseEnable(const int index) {
|
||||
}
|
||||
}
|
||||
|
||||
GasType ExperimentSettingForm::conver2GasType(const int index) {
|
||||
switch (index) {
|
||||
GasType ExperimentSettingForm::conver2GasType(const int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return GasType::NC;
|
||||
break; // 假设 GAS_AIR 是 gas_type 的枚举值
|
||||
@ -234,14 +242,16 @@ GasType ExperimentSettingForm::conver2GasType(const int index) {
|
||||
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;
|
||||
@ -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;
|
||||
}
|
||||
@ -394,10 +450,12 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -434,10 +493,12 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -466,10 +528,12 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -498,10 +563,12 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -530,10 +598,12 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
|
||||
|
||||
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,7 +616,8 @@ void ExperimentSettingForm::on_pushButton_deliverData_clicked() {
|
||||
if (!phaseCufoffTempAndTempFlowCheck(6,
|
||||
phase5CutoffTemp,
|
||||
phase6CutoffTemp,
|
||||
phase.temp_flow)) {
|
||||
phase.temp_flow))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -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));
|
||||
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));
|
||||
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,7 +753,8 @@ void ExperimentSettingForm::slotPhaseCheck() {
|
||||
}
|
||||
}
|
||||
|
||||
void ExperimentSettingForm::slotRecvPhaseInfo(const QByteArray &ba) {
|
||||
void ExperimentSettingForm::slotRecvPhaseInfo(const QByteArray &ba)
|
||||
{
|
||||
logde << "recv phase info ----------------------- ";
|
||||
|
||||
#if 1
|
||||
@ -676,7 +770,8 @@ void ExperimentSettingForm::slotRecvPhaseInfo(const QByteArray &ba) {
|
||||
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);
|
||||
@ -741,7 +836,8 @@ void ExperimentSettingForm::slotRecvPhaseInfo(const QByteArray &ba) {
|
||||
|
||||
// 解析 gas
|
||||
uint8_t gasType = *(localData + index);
|
||||
switch (gasType) {
|
||||
switch (gasType)
|
||||
{
|
||||
case NC:
|
||||
phase.gas = NC;
|
||||
break;
|
||||
@ -763,11 +859,15 @@ 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;
|
||||
}
|
||||
|
||||
@ -776,16 +876,20 @@ void ExperimentSettingForm::slotRecvPhaseInfo(const QByteArray &ba) {
|
||||
|
||||
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) {
|
||||
if (cutOffTempLineEdit)
|
||||
{
|
||||
cutOffTempLineEdit->setText(QString::number(phase.cutoff_temp, 'f', 3));
|
||||
cutOffTempLineEdit->setEnabled(true);
|
||||
}
|
||||
@ -793,21 +897,24 @@ void ExperimentSettingForm::slotRecvPhaseInfo(const QByteArray &ba) {
|
||||
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);
|
||||
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);
|
||||
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) {
|
||||
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,44 +335,10 @@ 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;
|
||||
}
|
||||
|
||||
@ -282,7 +346,8 @@ void LeftWidget::slotDeleteActionTriggered()
|
||||
bool isDir = fileInfo.isDir();
|
||||
|
||||
// 检查文件/目录是否存在
|
||||
if (!fileInfo.exists()) {
|
||||
if (!fileInfo.exists())
|
||||
{
|
||||
QMessageBox::warning(this, tr("警告"), tr("文件/目录不存在!"));
|
||||
return;
|
||||
}
|
||||
@ -293,20 +358,27 @@ void LeftWidget::slotDeleteActionTriggered()
|
||||
QMessageBox::Yes | QMessageBox::No,
|
||||
QMessageBox::No);
|
||||
|
||||
if (ret == QMessageBox::Yes) {
|
||||
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("删除失败!"));
|
||||
}
|
||||
}
|
||||
@ -319,15 +391,21 @@ 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;
|
||||
}
|
||||
}
|
||||
@ -339,18 +417,19 @@ bool LeftWidget::removeDir(const QString &dirPath)
|
||||
|
||||
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();
|
||||
}
|
||||
@ -362,12 +441,14 @@ void LeftWidget::slotCreateFolderActionTriggered()
|
||||
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;
|
||||
}
|
||||
@ -376,13 +457,15 @@ void LeftWidget::slotCreateFolderActionTriggered()
|
||||
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();
|
||||
|
||||
@ -394,7 +477,9 @@ void LeftWidget::slotCreateFolderActionTriggered()
|
||||
|
||||
// 展开当前目录并选中新创建的文件夹
|
||||
expandAndSelectItem(newFolderPath);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::critical(this, tr("错误"), tr("创建文件夹失败!"));
|
||||
}
|
||||
}
|
||||
@ -403,14 +488,17 @@ 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();
|
||||
}
|
||||
@ -453,7 +541,7 @@ void LeftWidget::reloadFileTree()
|
||||
// 创建根节点
|
||||
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);
|
||||
|
||||
@ -487,7 +575,8 @@ 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;
|
||||
}
|
||||
@ -496,10 +585,12 @@ void LeftWidget::buildFileTree(QTreeWidgetItem *parentItem, const QString &dirPa
|
||||
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());
|
||||
// 使用系统默认的目录图标
|
||||
@ -509,17 +600,22 @@ void LeftWidget::buildFileTree(QTreeWidgetItem *parentItem, const QString &dirPa
|
||||
|
||||
// 递归处理子目录
|
||||
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));
|
||||
}
|
||||
@ -533,11 +629,14 @@ void LeftWidget::saveExpandedState()
|
||||
|
||||
// 递归遍历所有项,保存展开的目录路径
|
||||
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());
|
||||
}
|
||||
}
|
||||
@ -553,12 +652,15 @@ void LeftWidget::restoreExpandedState()
|
||||
|
||||
// 递归遍历所有项,恢复展开状态
|
||||
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++;
|
||||
}
|
||||
@ -568,3 +670,135 @@ void LeftWidget::restoreExpandedState()
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -22,11 +22,13 @@ public:
|
||||
void reloadFileTree();
|
||||
|
||||
QString filePathCheck(const QString fileName, const QString folderPath);
|
||||
|
||||
// 确认删除文件
|
||||
void confirmDelete(bool enabled);
|
||||
signals:
|
||||
void sigSendAnalysisFileName(const QString &);
|
||||
void sigDeleteActionTriggered(const QString &);
|
||||
|
||||
private:
|
||||
void initData();
|
||||
void initFileName(QTreeWidgetItem *, const QString &folderPath);
|
||||
@ -38,22 +40,33 @@ private:
|
||||
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;
|
||||
#endif
|
||||
|
||||
QMenu *_contextMenu;
|
||||
|
||||
QAction *_deleteFileAction;
|
||||
QAction *_createFolderAction;
|
||||
QAction *_moveToFolderAction;
|
||||
QMenu *_moveToFolderSubMenu; // Add submenu for move to folder
|
||||
|
||||
QString _deleteFileActionFilePath;
|
||||
|
||||
// 保存展开状态的列表
|
||||
@ -61,4 +74,3 @@ private:
|
||||
};
|
||||
|
||||
#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