2025-12-11T16:15:35
This commit is contained in:
parent
8e3c534710
commit
0583d5f84f
26
.vscode/settings.json
vendored
Normal file
26
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"cmake.sourceDirectory": "D:/gitfile/analysis_tool/src",
|
||||||
|
"files.associations": {
|
||||||
|
"new": "cpp",
|
||||||
|
"__locale": "cpp",
|
||||||
|
"ios": "cpp",
|
||||||
|
"queue": "cpp",
|
||||||
|
"stack": "cpp",
|
||||||
|
"__config": "cpp",
|
||||||
|
"__bit_reference": "cpp",
|
||||||
|
"__hash_table": "cpp",
|
||||||
|
"__split_buffer": "cpp",
|
||||||
|
"__tree": "cpp",
|
||||||
|
"array": "cpp",
|
||||||
|
"deque": "cpp",
|
||||||
|
"initializer_list": "cpp",
|
||||||
|
"list": "cpp",
|
||||||
|
"map": "cpp",
|
||||||
|
"set": "cpp",
|
||||||
|
"string": "cpp",
|
||||||
|
"string_view": "cpp",
|
||||||
|
"unordered_map": "cpp",
|
||||||
|
"unordered_set": "cpp",
|
||||||
|
"vector": "cpp"
|
||||||
|
}
|
||||||
|
}
|
||||||
5
DSCAnalysisTool-release/bin/log/20251201.log
Normal file
5
DSCAnalysisTool-release/bin/log/20251201.log
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
[2025-12-01 10:46:10,897] main...
|
||||||
|
[2025-12-01 10:46:10,899] config file existed.
|
||||||
|
[2025-12-01 10:46:10,936] version:1.3.5.1
|
||||||
|
[2025-12-01 10:46:10,980] setEventHandlerEnable...0
|
||||||
|
[2025-12-01 10:46:31,805] serialport destructor.
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
2
src/.vscode/launch.json
vendored
2
src/.vscode/launch.json
vendored
@ -18,7 +18,7 @@
|
|||||||
],
|
],
|
||||||
"externalConsole": false,
|
"externalConsole": false,
|
||||||
"miDebuggerPath": "D:/qt/Qt5.14.2/5.14.2/mingw73_64/bin/gdb.exe",
|
"miDebuggerPath": "D:/qt/Qt5.14.2/5.14.2/mingw73_64/bin/gdb.exe",
|
||||||
"visualizerFile": "c:\\Users\\sunqu\\AppData\\Roaming\\Code\\User\\workspaceStorage\\7f93734217a2e383fe34beaf49d497fe\\tonka3000.qtvsctools\\qt.natvis.xml"
|
"visualizerFile": "c:\\Users\\sunqu\\AppData\\Roaming\\Trae CN\\User\\workspaceStorage\\7f93734217a2e383fe34beaf49d497fe\\tonka3000.qtvsctools\\qt.natvis.xml"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -9,7 +9,7 @@ CONFIG+=precompile_header
|
|||||||
PRECOMPILED_HEADER=stable.h
|
PRECOMPILED_HEADER=stable.h
|
||||||
|
|
||||||
#
|
#
|
||||||
VERSION = 1.3.7
|
VERSION = 1.4.0
|
||||||
# 设置目标文件名,包含版本号
|
# 设置目标文件名,包含版本号
|
||||||
TARGET = DSCAnalysisTool_$${VERSION}
|
TARGET = DSCAnalysisTool_$${VERSION}
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,8 @@
|
|||||||
|
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
|
||||||
namespace Global {
|
namespace Global
|
||||||
|
{
|
||||||
Mode _mode = Mode::Analysis;
|
Mode _mode = Mode::Analysis;
|
||||||
|
|
||||||
AxisMode _axisMode = AxisMode::SingleY;
|
AxisMode _axisMode = AxisMode::SingleY;
|
||||||
@ -35,12 +36,15 @@ namespace Global {
|
|||||||
// 实验文件
|
// 实验文件
|
||||||
QStringList _fileList;
|
QStringList _fileList;
|
||||||
|
|
||||||
QString converDoubleToStr(const double num) {
|
QString converDoubleToStr(const double num)
|
||||||
|
{
|
||||||
return QString::number(num, 'f', 3);
|
return QString::number(num, 'f', 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void quadraticLeastSquaresFit(double x[], double y[], int n, double coeff[]) {
|
void quadraticLeastSquaresFit(double x[], double y[], int n, double coeff[])
|
||||||
if (n < 3) {
|
{
|
||||||
|
if (n < 3)
|
||||||
|
{
|
||||||
throw std::invalid_argument("At least 3 data points are required for quadratic fitting");
|
throw std::invalid_argument("At least 3 data points are required for quadratic fitting");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +52,8 @@ namespace Global {
|
|||||||
double sum_y = 0, sum_xy = 0, sum_x2y = 0;
|
double sum_y = 0, sum_xy = 0, sum_x2y = 0;
|
||||||
|
|
||||||
// 计算各项累加和
|
// 计算各项累加和
|
||||||
for (int i = 0; i < n; ++i) {
|
for (int i = 0; i < n; ++i)
|
||||||
|
{
|
||||||
double xi = x[i];
|
double xi = x[i];
|
||||||
double xi2 = xi * xi;
|
double xi2 = xi * xi;
|
||||||
double xi3 = xi2 * xi;
|
double xi3 = xi2 * xi;
|
||||||
@ -72,24 +77,30 @@ namespace Global {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 高斯消元法解方程组
|
// 高斯消元法解方程组
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
// 部分主元选择
|
// 部分主元选择
|
||||||
int maxRow = i;
|
int maxRow = i;
|
||||||
for (int k = i + 1; k < 3; ++k) {
|
for (int k = i + 1; k < 3; ++k)
|
||||||
if (std::abs(matrix[k][i]) > std::abs(matrix[maxRow][i])) {
|
{
|
||||||
|
if (std::abs(matrix[k][i]) > std::abs(matrix[maxRow][i]))
|
||||||
|
{
|
||||||
maxRow = k;
|
maxRow = k;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 交换行
|
// 交换行
|
||||||
for (int k = i; k < 4; ++k) {
|
for (int k = i; k < 4; ++k)
|
||||||
|
{
|
||||||
std::swap(matrix[i][k], matrix[maxRow][k]);
|
std::swap(matrix[i][k], matrix[maxRow][k]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 消元
|
// 消元
|
||||||
for (int k = i + 1; k < 3; ++k) {
|
for (int k = i + 1; k < 3; ++k)
|
||||||
|
{
|
||||||
double factor = matrix[k][i] / matrix[i][i];
|
double factor = matrix[k][i] / matrix[i][i];
|
||||||
for (int j = i; j < 4; ++j) {
|
for (int j = i; j < 4; ++j)
|
||||||
|
{
|
||||||
matrix[k][j] -= factor * matrix[i][j];
|
matrix[k][j] -= factor * matrix[i][j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,13 +113,18 @@ namespace Global {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 计算一元一次函数在给定区间内开始变成负值的点
|
// 计算一元一次函数在给定区间内开始变成负值的点
|
||||||
double findNegativeStartPoint(double m, double b, double start, double end) {
|
double findNegativeStartPoint(double m, double b, double start, double end)
|
||||||
|
{
|
||||||
// 处理斜率为零的情况
|
// 处理斜率为零的情况
|
||||||
if (m == 0) {
|
if (m == 0)
|
||||||
|
{
|
||||||
// 当斜率为 0 时,函数值为常数 b
|
// 当斜率为 0 时,函数值为常数 b
|
||||||
if (b < 0) {
|
if (b < 0)
|
||||||
|
{
|
||||||
return start; // 若 b 为负,函数在区间起始点就为负
|
return start; // 若 b 为负,函数在区间起始点就为负
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
return std::numeric_limits<double>::infinity(); // 若 b 非负,函数在区间内不会变负
|
return std::numeric_limits<double>::infinity(); // 若 b 非负,函数在区间内不会变负
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -117,19 +133,25 @@ namespace Global {
|
|||||||
double zeroPoint = -b / m;
|
double zeroPoint = -b / m;
|
||||||
|
|
||||||
// 检查零点是否在给定区间内
|
// 检查零点是否在给定区间内
|
||||||
if (zeroPoint >= start && zeroPoint <= end) {
|
if (zeroPoint >= start && zeroPoint <= end)
|
||||||
|
{
|
||||||
return zeroPoint; // 零点在区间内,函数在此点开始变负
|
return zeroPoint; // 零点在区间内,函数在此点开始变负
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据斜率正负判断函数单调性,进而判断函数在区间内是否会变负
|
// 根据斜率正负判断函数单调性,进而判断函数在区间内是否会变负
|
||||||
if (m > 0) {
|
if (m > 0)
|
||||||
|
{
|
||||||
// 斜率大于 0,函数单调递增
|
// 斜率大于 0,函数单调递增
|
||||||
if (m * start + b < 0) {
|
if (m * start + b < 0)
|
||||||
|
{
|
||||||
return start; // 起始点函数值为负,函数在起始点就为负
|
return start; // 起始点函数值为负,函数在起始点就为负
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// 斜率小于 0,函数单调递减
|
// 斜率小于 0,函数单调递减
|
||||||
if (m * end + b < 0) {
|
if (m * end + b < 0)
|
||||||
|
{
|
||||||
return end; // 结束点函数值为负,函数在结束点开始为负
|
return end; // 结束点函数值为负,函数在结束点开始为负
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -138,22 +160,26 @@ namespace Global {
|
|||||||
return std::numeric_limits<double>::infinity();
|
return std::numeric_limits<double>::infinity();
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearExperimentData() {
|
void clearExperimentData()
|
||||||
|
{
|
||||||
_curveExperimentDataVtr.clear();
|
_curveExperimentDataVtr.clear();
|
||||||
_currentCurveExperimentDataPtr = nullptr;
|
_currentCurveExperimentDataPtr = nullptr;
|
||||||
_currentPhase = -1;
|
_currentPhase = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isZero(double value, double epsilon) {
|
bool isZero(double value, double epsilon)
|
||||||
|
{
|
||||||
return std::abs(value) < epsilon;
|
return std::abs(value) < epsilon;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isEqual(const double a, const double b) {
|
bool isEqual(const double a, const double b)
|
||||||
|
{
|
||||||
const double tolerance = 1e-5; // 容差值,可以根据需要调整
|
const double tolerance = 1e-5; // 容差值,可以根据需要调整
|
||||||
return std::fabs(a - b) < tolerance;
|
return std::fabs(a - b) < tolerance;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString getFileName(const QString filePath) {
|
QString getFileName(const QString filePath)
|
||||||
|
{
|
||||||
QFileInfo fileInfo(filePath);
|
QFileInfo fileInfo(filePath);
|
||||||
|
|
||||||
// 获取文件的后缀名并转换为小写,方便比较
|
// 获取文件的后缀名并转换为小写,方便比较
|
||||||
@ -162,20 +188,22 @@ namespace Global {
|
|||||||
return fileInfo.fileName();
|
return fileInfo.fileName();
|
||||||
}
|
}
|
||||||
|
|
||||||
double converStrToDouble(const QString str) {
|
double converStrToDouble(const QString str)
|
||||||
|
{
|
||||||
bool ok;
|
bool ok;
|
||||||
double value = str.toDouble(&ok); // 将字符串转换为 double,并检查是否成功
|
double value = str.toDouble(&ok); // 将字符串转换为 double,并检查是否成功
|
||||||
if (!ok) {
|
if (!ok)
|
||||||
|
{
|
||||||
qDebug() << "转换失败,输入的字符串不是有效的数字";
|
qDebug() << "转换失败,输入的字符串不是有效的数字";
|
||||||
return 0.0; // 如果转换失败,返回默认值
|
return 0.0; // 如果转换失败,返回默认值
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
bool isFileExist(const QString &fileName) {
|
bool isFileExist(const QString &fileName)
|
||||||
|
{
|
||||||
return _fileList.contains(fileName);
|
return _fileList.contains(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void updateFileList()
|
void updateFileList()
|
||||||
{
|
{
|
||||||
_fileList.clear();
|
_fileList.clear();
|
||||||
|
|||||||
@ -31,7 +31,8 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
_coefficientSelectionForm(new CoefficientSelectionForm(this)),
|
_coefficientSelectionForm(new CoefficientSelectionForm(this)),
|
||||||
_printPreviewForm(new PrintPreviewForm(this)),
|
_printPreviewForm(new PrintPreviewForm(this)),
|
||||||
_axisSettingForm(new AxisSettingForm(this)),
|
_axisSettingForm(new AxisSettingForm(this)),
|
||||||
_manuallyStopTheExperimentFlag(false) {
|
_manuallyStopTheExperimentFlag(false)
|
||||||
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
ui->actionOITAutoAnalysisMode->setVisible(false);
|
ui->actionOITAutoAnalysisMode->setVisible(false);
|
||||||
ui->toolBar->setWindowTitle("工具栏");
|
ui->toolBar->setWindowTitle("工具栏");
|
||||||
@ -84,44 +85,58 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
// ui->actionStop->setEnabled(false);
|
// ui->actionStop->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow() {
|
MainWindow::~MainWindow()
|
||||||
|
{
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::slotContextMenuShow(const QPoint point) {
|
void MainWindow::slotContextMenuShow(const QPoint point)
|
||||||
|
{
|
||||||
_contextMenu->exec(point);
|
_contextMenu->exec(point);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::slotUpdateStatusbarMsg(const QString msg) {
|
void MainWindow::slotUpdateStatusbarMsg(const QString msg)
|
||||||
|
{
|
||||||
ui->statusbar->showMessage(msg);
|
ui->statusbar->showMessage(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::slotOITAutoAnalysis(const double x1, const double x2) {
|
void MainWindow::slotOITAutoAnalysis(const double x1, const double x2)
|
||||||
|
{
|
||||||
on_actionStop_triggered();
|
on_actionStop_triggered();
|
||||||
_centralWidget->setAnalysisMode(CentralWidget::AnalysisMode::OIT);
|
_centralWidget->setAnalysisMode(CentralWidget::AnalysisMode::OIT);
|
||||||
_centralWidget->setVerticalLineRange(x1, x2);
|
_centralWidget->setVerticalLineRange(x1, x2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::slotStartExperiment() {
|
void MainWindow::slotStartExperiment()
|
||||||
|
{
|
||||||
startExperimentByDeviceInfo();
|
startExperimentByDeviceInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::closeEvent(QCloseEvent *event) {
|
void MainWindow::closeEvent(QCloseEvent *event)
|
||||||
|
{
|
||||||
// 弹出确认对话框
|
// 弹出确认对话框
|
||||||
QMessageBox::StandardButton reply;
|
QMessageBox::StandardButton reply;
|
||||||
reply = QMessageBox::question(this, "确认退出", "你确定要退出吗?",
|
reply = QMessageBox::question(this, "确认退出", "你确定要退出吗?",
|
||||||
QMessageBox::Yes | QMessageBox::No);
|
QMessageBox::Yes | QMessageBox::No);
|
||||||
if (reply == QMessageBox::Yes) {
|
if (reply == QMessageBox::Yes)
|
||||||
|
{
|
||||||
event->accept(); // 接受关闭事件,关闭窗口
|
event->accept(); // 接受关闭事件,关闭窗口
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
event->ignore(); // 忽略关闭事件,不关闭窗口
|
event->ignore(); // 忽略关闭事件,不关闭窗口
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::connections() {
|
void MainWindow::connections()
|
||||||
|
{
|
||||||
// ui
|
// ui
|
||||||
connect(_expertmentSettingForm, &ExperimentSettingForm::sigDeliverData,
|
connect(_expertmentSettingForm, &ExperimentSettingForm::sigDeliverData,
|
||||||
SerialPort::instance(), &SerialPort::slotDeliverData);
|
SerialPort::instance(), &SerialPort::slotDeliverData);
|
||||||
|
|
||||||
|
// 左侧文件管理子窗口相关函数
|
||||||
|
connect(_leftWidget, &LeftWidget::sigDeleteActionTriggered,
|
||||||
|
this, &MainWindow::slotDeleteActionTriggered);
|
||||||
#if 1
|
#if 1
|
||||||
// SerialPort.
|
// SerialPort.
|
||||||
connect(SerialPort::instance(), &SerialPort::sigSendCommonData,
|
connect(SerialPort::instance(), &SerialPort::sigSendCommonData,
|
||||||
@ -172,7 +187,8 @@ void MainWindow::connections() {
|
|||||||
_centralWidget, &CentralWidget::slotAnalysisSettingCancel);
|
_centralWidget, &CentralWidget::slotAnalysisSettingCancel);
|
||||||
|
|
||||||
connect(_centralWidget, &CentralWidget::sigRightDockWidgetHide,
|
connect(_centralWidget, &CentralWidget::sigRightDockWidgetHide,
|
||||||
[&]() { _rightWidget->hide(); });
|
[&]()
|
||||||
|
{ _rightWidget->hide(); });
|
||||||
|
|
||||||
connect(_degreeOfCrystallinityForm, &DegreeOfCrystallinityForm::sigDrawCustomText,
|
connect(_degreeOfCrystallinityForm, &DegreeOfCrystallinityForm::sigDrawCustomText,
|
||||||
_centralWidget, &CentralWidget::slotDrawCustomText);
|
_centralWidget, &CentralWidget::slotDrawCustomText);
|
||||||
@ -196,13 +212,17 @@ void MainWindow::connections() {
|
|||||||
this, &MainWindow::slotOITAutoAnalysis);
|
this, &MainWindow::slotOITAutoAnalysis);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setActionEnable(const bool flag) {
|
void MainWindow::setActionEnable(const bool flag)
|
||||||
if (flag) {
|
{
|
||||||
|
if (flag)
|
||||||
|
{
|
||||||
ui->actionNew->setEnabled(true);
|
ui->actionNew->setEnabled(true);
|
||||||
ui->actionStart->setEnabled(true);
|
ui->actionStart->setEnabled(true);
|
||||||
ui->actionStop->setEnabled(true);
|
ui->actionStop->setEnabled(true);
|
||||||
ui->actionRealTimeWidget->setEnabled(true);
|
ui->actionRealTimeWidget->setEnabled(true);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ui->actionNew->setEnabled(false);
|
ui->actionNew->setEnabled(false);
|
||||||
ui->actionStart->setEnabled(false);
|
ui->actionStart->setEnabled(false);
|
||||||
ui->actionStop->setEnabled(false);
|
ui->actionStop->setEnabled(false);
|
||||||
@ -210,7 +230,8 @@ void MainWindow::setActionEnable(const bool flag) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setSubWidgetAttribute(QWidget *widget) {
|
void MainWindow::setSubWidgetAttribute(QWidget *widget)
|
||||||
|
{
|
||||||
widget->setWindowModality(Qt::ApplicationModal);
|
widget->setWindowModality(Qt::ApplicationModal);
|
||||||
widget->setWindowFlags(Qt::Dialog);
|
widget->setWindowFlags(Qt::Dialog);
|
||||||
|
|
||||||
@ -262,28 +283,38 @@ bool MainWindow::saveAnalysisFile(const QString fileName)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool MainWindow::saveFile(const QString fileName, const Global::Mode mode,
|
bool MainWindow::saveFile(const QString fileName, const Global::Mode mode,
|
||||||
QString &finalFileName, const bool autoSaveFlag) {
|
QString &finalFileName, const bool autoSaveFlag)
|
||||||
|
{
|
||||||
logde << "save file...";
|
logde << "save file...";
|
||||||
|
|
||||||
QString localFileName = fileName;
|
QString localFileName = fileName;
|
||||||
if (fileName.isEmpty()) {
|
if (fileName.isEmpty())
|
||||||
|
{
|
||||||
localFileName = "new";
|
localFileName = "new";
|
||||||
}
|
}
|
||||||
|
|
||||||
QString folder;
|
QString folder;
|
||||||
if (mode == Global::Mode::None) {
|
if (mode == Global::Mode::None)
|
||||||
|
{
|
||||||
folder = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
|
folder = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
|
||||||
} else if (mode == Global::Mode::Analysis) {
|
}
|
||||||
|
else if (mode == Global::Mode::Analysis)
|
||||||
|
{
|
||||||
folder = Global::AnalysisStateFolder;
|
folder = Global::AnalysisStateFolder;
|
||||||
} else if (mode == Global::Mode::Experiment) {
|
}
|
||||||
|
else if (mode == Global::Mode::Experiment)
|
||||||
|
{
|
||||||
folder = Global::SampleDataFloder;
|
folder = Global::SampleDataFloder;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString filePath;
|
QString filePath;
|
||||||
if (autoSaveFlag) {
|
if (autoSaveFlag)
|
||||||
|
{
|
||||||
localFileName = _leftWidget->filePathCheck(fileName, folder);
|
localFileName = _leftWidget->filePathCheck(fileName, folder);
|
||||||
filePath = folder + "/" + localFileName + ".xlsx";
|
filePath = folder + "/" + localFileName + ".xlsx";
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
QString xlsxfilePath = folder + "/" + localFileName + ".xlsx";
|
QString xlsxfilePath = folder + "/" + localFileName + ".xlsx";
|
||||||
filePath = QFileDialog::getSaveFileName(nullptr, "Save experiment file",
|
filePath = QFileDialog::getSaveFileName(nullptr, "Save experiment file",
|
||||||
xlsxfilePath, "Excel Files (*.xlsx)");
|
xlsxfilePath, "Excel Files (*.xlsx)");
|
||||||
@ -293,17 +324,22 @@ bool MainWindow::saveFile(const QString fileName, const Global::Mode mode,
|
|||||||
|
|
||||||
logde << "filePath:" << filePath.toStdString();
|
logde << "filePath:" << filePath.toStdString();
|
||||||
|
|
||||||
if (filePath.isEmpty()) {
|
if (filePath.isEmpty())
|
||||||
|
{
|
||||||
qDebug() << "User cancel the operation.";
|
qDebug() << "User cancel the operation.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save file.
|
// Save file.
|
||||||
if (mode == Global::Mode::Analysis) {
|
if (mode == Global::Mode::Analysis)
|
||||||
if (Global::_curveFileDataVtr.empty()) {
|
{
|
||||||
|
if (Global::_curveFileDataVtr.empty())
|
||||||
|
{
|
||||||
// 分析模式下,但是文件数据为空,说明做完实验没有保存数据。
|
// 分析模式下,但是文件数据为空,说明做完实验没有保存数据。
|
||||||
XlsxHandler::writeExperimentFile(filePath);
|
XlsxHandler::writeExperimentFile(filePath);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// 分析模式下,存在文件数据,将文件数据写入文件。
|
// 分析模式下,存在文件数据,将文件数据写入文件。
|
||||||
XlsxHandler::writeXlsxFile(filePath);
|
XlsxHandler::writeXlsxFile(filePath);
|
||||||
#if 0
|
#if 0
|
||||||
@ -316,36 +352,46 @@ bool MainWindow::saveFile(const QString fileName, const Global::Mode mode,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
} else if (mode == Global::Mode::Experiment) {
|
}
|
||||||
|
else if (mode == Global::Mode::Experiment)
|
||||||
|
{
|
||||||
XlsxHandler::writeExperimentFile(filePath);
|
XlsxHandler::writeExperimentFile(filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::smoothness(const int level) {
|
void MainWindow::smoothness(const int level)
|
||||||
|
{
|
||||||
logde << "smoothness...";
|
logde << "smoothness...";
|
||||||
slotUpdateStatusbarMsg("数据平滑计算中...");
|
slotUpdateStatusbarMsg("数据平滑计算中...");
|
||||||
|
|
||||||
if (!Global::_curveExperimentDataVtr.empty()) {
|
if (!Global::_curveExperimentDataVtr.empty())
|
||||||
|
{
|
||||||
// 当前数据为实验数据时,需要把所有的当前实验数据都进行平滑处理。
|
// 当前数据为实验数据时,需要把所有的当前实验数据都进行平滑处理。
|
||||||
|
|
||||||
// 删除所有objectName为experiment的curve.
|
// 删除所有objectName为experiment的curve.
|
||||||
_centralWidget->deleteCurveByObjectName(Global::ObjectNameExperiemnt);
|
_centralWidget->deleteCurveByObjectName(Global::ObjectNameExperiemnt);
|
||||||
// 添加所有平滑后的curve.
|
// 添加所有平滑后的curve.
|
||||||
for (auto &item : Global::_curveExperimentDataVtr) {
|
for (auto &item : Global::_curveExperimentDataVtr)
|
||||||
|
{
|
||||||
item.smoothDataVtr = smoothnessDetail(level, item.dataVtr);
|
item.smoothDataVtr = smoothnessDetail(level, item.dataVtr);
|
||||||
item.curve = _centralWidget->addCurveData(item.smoothDataVtr,
|
item.curve = _centralWidget->addCurveData(item.smoothDataVtr,
|
||||||
Global::ObjectNameExperiemnt);
|
Global::ObjectNameExperiemnt);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// 当前数据为文件分析数据时,需要把当前文件下的所有数据都进行平滑处理。
|
// 当前数据为文件分析数据时,需要把当前文件下的所有数据都进行平滑处理。
|
||||||
QString selectedCurveObjectName = _centralWidget->getCurrentCurve()->objectName();
|
QString selectedCurveObjectName = _centralWidget->getCurrentCurve()->objectName();
|
||||||
_centralWidget->deleteCurveByObjectName(selectedCurveObjectName);
|
_centralWidget->deleteCurveByObjectName(selectedCurveObjectName);
|
||||||
|
|
||||||
for (Global::CurveFileData &cfd : Global::_curveFileDataVtr) {
|
for (Global::CurveFileData &cfd : Global::_curveFileDataVtr)
|
||||||
if (selectedCurveObjectName.contains(cfd.filePath)) {
|
{
|
||||||
for (Global::PhaseTotalInfo &pti : cfd.phaseTotalVtr) {
|
if (selectedCurveObjectName.contains(cfd.filePath))
|
||||||
|
{
|
||||||
|
for (Global::PhaseTotalInfo &pti : cfd.phaseTotalVtr)
|
||||||
|
{
|
||||||
pti.smoothDataVtr = smoothnessDetail(level, pti.dataVtr);
|
pti.smoothDataVtr = smoothnessDetail(level, pti.dataVtr);
|
||||||
pti.curve = _centralWidget->addCurveData(pti.smoothDataVtr,
|
pti.curve = _centralWidget->addCurveData(pti.smoothDataVtr,
|
||||||
cfd.filePath);
|
cfd.filePath);
|
||||||
@ -355,7 +401,8 @@ void MainWindow::smoothness(const int level) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<Global::ExperimentData> MainWindow::smoothnessDetail(const int level, const QVector<Global::ExperimentData> &dataVtr) {
|
QVector<Global::ExperimentData> MainWindow::smoothnessDetail(const int level, const QVector<Global::ExperimentData> &dataVtr)
|
||||||
|
{
|
||||||
Lowess::Config config;
|
Lowess::Config config;
|
||||||
config.smoothingFactor = level * 0.01;
|
config.smoothingFactor = level * 0.01;
|
||||||
config.robustnessIterations = 3;
|
config.robustnessIterations = 3;
|
||||||
@ -363,10 +410,14 @@ QVector<Global::ExperimentData> MainWindow::smoothnessDetail(const int level, co
|
|||||||
std::vector<double> x;
|
std::vector<double> x;
|
||||||
std::vector<double> y;
|
std::vector<double> y;
|
||||||
|
|
||||||
for (const Global::ExperimentData &ed : dataVtr) {
|
for (const Global::ExperimentData &ed : dataVtr)
|
||||||
if (Global::_axisMode == Global::AxisMode::SingleY) {
|
{
|
||||||
|
if (Global::_axisMode == Global::AxisMode::SingleY)
|
||||||
|
{
|
||||||
x.push_back(ed.sampleTemp);
|
x.push_back(ed.sampleTemp);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
x.push_back(ed.runTime);
|
x.push_back(ed.runTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -385,7 +436,8 @@ QVector<Global::ExperimentData> MainWindow::smoothnessDetail(const int level, co
|
|||||||
ui->statusbar->showMessage("数据平滑计算中...");
|
ui->statusbar->showMessage("数据平滑计算中...");
|
||||||
|
|
||||||
std::vector<double> yest = Lowess::smooth(x, y, config);
|
std::vector<double> yest = Lowess::smooth(x, y, config);
|
||||||
if (yest.empty()) {
|
if (yest.empty())
|
||||||
|
{
|
||||||
slotUpdateStatusbarMsg("数据平滑完成.");
|
slotUpdateStatusbarMsg("数据平滑完成.");
|
||||||
return resultVtr;
|
return resultVtr;
|
||||||
}
|
}
|
||||||
@ -396,12 +448,16 @@ QVector<Global::ExperimentData> MainWindow::smoothnessDetail(const int level, co
|
|||||||
|
|
||||||
// result data vector.
|
// result data vector.
|
||||||
|
|
||||||
for (int i = 0; i < x.size(); i++) {
|
for (int i = 0; i < x.size(); i++)
|
||||||
|
{
|
||||||
Global::ExperimentData ed;
|
Global::ExperimentData ed;
|
||||||
if (Global::_axisMode == Global::AxisMode::SingleY) {
|
if (Global::_axisMode == Global::AxisMode::SingleY)
|
||||||
|
{
|
||||||
ed.sampleTemp = x.at(i);
|
ed.sampleTemp = x.at(i);
|
||||||
ed.runTime = dataVtr.at(i).runTime;
|
ed.runTime = dataVtr.at(i).runTime;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ed.runTime = x.at(i);
|
ed.runTime = x.at(i);
|
||||||
ed.sampleTemp = dataVtr.at(i).sampleTemp;
|
ed.sampleTemp = dataVtr.at(i).sampleTemp;
|
||||||
}
|
}
|
||||||
@ -415,7 +471,8 @@ QVector<Global::ExperimentData> MainWindow::smoothnessDetail(const int level, co
|
|||||||
return resultVtr;
|
return resultVtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::smoothnessExperimentData(const int level) {
|
void MainWindow::smoothnessExperimentData(const int level)
|
||||||
|
{
|
||||||
#if 0
|
#if 0
|
||||||
for(int i = 0;i < Global::_curveExperimentDataVtr.size();i++){
|
for(int i = 0;i < Global::_curveExperimentDataVtr.size();i++){
|
||||||
Global::CurveExperimentData ced = Global::_curveExperimentDataVtr.at(i);
|
Global::CurveExperimentData ced = Global::_curveExperimentDataVtr.at(i);
|
||||||
@ -423,12 +480,14 @@ void MainWindow::smoothnessExperimentData(const int level) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (auto &item : Global::_curveExperimentDataVtr) {
|
for (auto &item : Global::_curveExperimentDataVtr)
|
||||||
|
{
|
||||||
smoothnessDetail(level, item.dataVtr);
|
smoothnessDetail(level, item.dataVtr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::startExperiment() {
|
void MainWindow::startExperiment()
|
||||||
|
{
|
||||||
QByteArray ba = DataParser::setDeviceStartStop(DeviceStartMode::Start);
|
QByteArray ba = DataParser::setDeviceStartStop(DeviceStartMode::Start);
|
||||||
|
|
||||||
QString hexData = ba.toHex(' ');
|
QString hexData = ba.toHex(' ');
|
||||||
@ -445,7 +504,8 @@ void MainWindow::startExperiment() {
|
|||||||
ui->menu_4->menuAction()->setEnabled(false);
|
ui->menu_4->menuAction()->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::startExperimentByDeviceInfo() {
|
void MainWindow::startExperimentByDeviceInfo()
|
||||||
|
{
|
||||||
Global::_mode = Global::Mode::Experiment;
|
Global::_mode = Global::Mode::Experiment;
|
||||||
_manuallyStopTheExperimentFlag = false;
|
_manuallyStopTheExperimentFlag = false;
|
||||||
_centralWidget->startExperiment();
|
_centralWidget->startExperiment();
|
||||||
@ -454,15 +514,18 @@ void MainWindow::startExperimentByDeviceInfo() {
|
|||||||
Global::clearExperimentData();
|
Global::clearExperimentData();
|
||||||
}
|
}
|
||||||
// 停止实验
|
// 停止实验
|
||||||
void MainWindow::on_actionStop_triggered() {
|
void MainWindow::on_actionStop_triggered()
|
||||||
|
{
|
||||||
logde << " Stop experiment ...++++++++++++++++++";
|
logde << " Stop experiment ...++++++++++++++++++";
|
||||||
|
|
||||||
if (!SerialPort::instance()->isOpen()) {
|
if (!SerialPort::instance()->isOpen())
|
||||||
|
{
|
||||||
showMesgBox("设备未连接,请先连接设备。");
|
showMesgBox("设备未连接,请先连接设备。");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Global::_mode == Global::Mode::Experiment) {
|
if (Global::_mode == Global::Mode::Experiment)
|
||||||
|
{
|
||||||
QByteArray ba = DataParser::setDeviceStartStop(DeviceStartMode::Stop);
|
QByteArray ba = DataParser::setDeviceStartStop(DeviceStartMode::Stop);
|
||||||
SerialPort::instance()->slotSendData(ba);
|
SerialPort::instance()->slotSendData(ba);
|
||||||
|
|
||||||
@ -477,7 +540,8 @@ void MainWindow::on_actionStop_triggered() {
|
|||||||
logde << "on_actionStop_triggered saveFile ...";
|
logde << "on_actionStop_triggered saveFile ...";
|
||||||
|
|
||||||
QString finalFileName;
|
QString finalFileName;
|
||||||
if (saveFile(Global::_experimentInfo.sampleName, Global::Mode::Experiment, finalFileName, true)) {
|
if (saveFile(Global::_experimentInfo.sampleName, Global::Mode::Experiment, finalFileName, true))
|
||||||
|
{
|
||||||
_leftWidget->reloadFileName();
|
_leftWidget->reloadFileName();
|
||||||
|
|
||||||
QString str = QString("%1 文件保存成功。").arg(finalFileName);
|
QString str = QString("%1 文件保存成功。").arg(finalFileName);
|
||||||
@ -492,19 +556,23 @@ void MainWindow::on_actionStop_triggered() {
|
|||||||
ui->menu_4->menuAction()->setEnabled(true);
|
ui->menu_4->menuAction()->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionNew_triggered() {
|
void MainWindow::on_actionNew_triggered()
|
||||||
if (!SerialPort::instance()->isOpen()) {
|
{
|
||||||
|
if (!SerialPort::instance()->isOpen())
|
||||||
|
{
|
||||||
showMesgBox("设备未连接,请先连接设备。");
|
showMesgBox("设备未连接,请先连接设备。");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_expertmentSettingForm->show();
|
_expertmentSettingForm->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionStart_triggered() {
|
void MainWindow::on_actionStart_triggered()
|
||||||
|
{
|
||||||
logde << "start experiment,set soft into experiment mode.";
|
logde << "start experiment,set soft into experiment mode.";
|
||||||
logde << "```````````````````````````````";
|
logde << "```````````````````````````````";
|
||||||
|
|
||||||
if (!SerialPort::instance()->isOpen()) {
|
if (!SerialPort::instance()->isOpen())
|
||||||
|
{
|
||||||
showMesgBox("设备未连接,请先连接设备。");
|
showMesgBox("设备未连接,请先连接设备。");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -514,19 +582,23 @@ void MainWindow::on_actionStart_triggered() {
|
|||||||
startExperiment();
|
startExperiment();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionReadOnly_triggered() {
|
void MainWindow::on_actionReadOnly_triggered()
|
||||||
|
{
|
||||||
Global::_mode = Global::Mode::Experiment;
|
Global::_mode = Global::Mode::Experiment;
|
||||||
SerialPort::instance()->openSp();
|
SerialPort::instance()->openSp();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionRealTimeWidget_triggered() {
|
void MainWindow::on_actionRealTimeWidget_triggered()
|
||||||
|
{
|
||||||
_realTimeDataForm->show();
|
_realTimeDataForm->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::slotSaveExperimentalDataMsgBox() {
|
void MainWindow::slotSaveExperimentalDataMsgBox()
|
||||||
|
{
|
||||||
logde << "_manuallyStopTheExperimentFlag:" << _manuallyStopTheExperimentFlag;
|
logde << "_manuallyStopTheExperimentFlag:" << _manuallyStopTheExperimentFlag;
|
||||||
|
|
||||||
if (_manuallyStopTheExperimentFlag) {
|
if (_manuallyStopTheExperimentFlag)
|
||||||
|
{
|
||||||
logde << "_manuallyStopTheExperimentFlag...";
|
logde << "_manuallyStopTheExperimentFlag...";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -537,7 +609,8 @@ void MainWindow::slotSaveExperimentalDataMsgBox() {
|
|||||||
if (saveFile(Global::_experimentInfo.sampleName,
|
if (saveFile(Global::_experimentInfo.sampleName,
|
||||||
Global::Mode::Experiment,
|
Global::Mode::Experiment,
|
||||||
finalFileName,
|
finalFileName,
|
||||||
true)) {
|
true))
|
||||||
|
{
|
||||||
_leftWidget->reloadFileName();
|
_leftWidget->reloadFileName();
|
||||||
|
|
||||||
QString str = QString("%1 文件保存成功。").arg(finalFileName);
|
QString str = QString("%1 文件保存成功。").arg(finalFileName);
|
||||||
@ -564,10 +637,12 @@ void MainWindow::slotSaveExperimentalDataMsgBox() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionConnectToDev_triggered() {
|
void MainWindow::on_actionConnectToDev_triggered()
|
||||||
|
{
|
||||||
logde << "connect to device...";
|
logde << "connect to device...";
|
||||||
|
|
||||||
if (SerialPort::instance()->isOpen()) {
|
if (SerialPort::instance()->isOpen())
|
||||||
|
{
|
||||||
logde << "close device.";
|
logde << "close device.";
|
||||||
|
|
||||||
SerialPort::instance()->closeSp();
|
SerialPort::instance()->closeSp();
|
||||||
@ -580,10 +655,13 @@ void MainWindow::on_actionConnectToDev_triggered() {
|
|||||||
QString str("设备已断开。");
|
QString str("设备已断开。");
|
||||||
slotUpdateStatusbarMsg(str);
|
slotUpdateStatusbarMsg(str);
|
||||||
showMesgBox(str);
|
showMesgBox(str);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
logde << "open device.";
|
logde << "open device.";
|
||||||
|
|
||||||
if (SerialPort::instance()->openSp()) {
|
if (SerialPort::instance()->openSp())
|
||||||
|
{
|
||||||
setActionEnable(true);
|
setActionEnable(true);
|
||||||
// Global::instance()->setMode(Global::Mode::ConnectedToDev);
|
// Global::instance()->setMode(Global::Mode::ConnectedToDev);
|
||||||
Global::_mode = Global::Mode::ConnectedToDev;
|
Global::_mode = Global::Mode::ConnectedToDev;
|
||||||
@ -600,38 +678,46 @@ void MainWindow::on_actionConnectToDev_triggered() {
|
|||||||
showMesgBox(str);
|
showMesgBox(str);
|
||||||
|
|
||||||
logde << "open serial port success. ";
|
logde << "open serial port success. ";
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// QMessageBox::warning(this, "warnning", "Serial Port open failed.");
|
// QMessageBox::warning(this, "warnning", "Serial Port open failed.");
|
||||||
showMesgBox("设备打开失败。");
|
showMesgBox("设备打开失败。");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionStartPoint_triggered() {
|
void MainWindow::on_actionStartPoint_triggered()
|
||||||
|
{
|
||||||
logde << "start experiment...";
|
logde << "start experiment...";
|
||||||
|
|
||||||
_rightWidget->show();
|
_rightWidget->show();
|
||||||
_centralWidget->setAnalysisMode(CentralWidget::AnalysisMode::StartPoint);
|
_centralWidget->setAnalysisMode(CentralWidget::AnalysisMode::StartPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionStopPoint_triggered() {
|
void MainWindow::on_actionStopPoint_triggered()
|
||||||
|
{
|
||||||
_rightWidget->show();
|
_rightWidget->show();
|
||||||
_centralWidget->setAnalysisMode(CentralWidget::AnalysisMode::StopPoint);
|
_centralWidget->setAnalysisMode(CentralWidget::AnalysisMode::StopPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionNumericalLabel_triggered() {
|
void MainWindow::on_actionNumericalLabel_triggered()
|
||||||
|
{
|
||||||
_rightWidget->show();
|
_rightWidget->show();
|
||||||
_centralWidget->setAnalysisMode(CentralWidget::AnalysisMode::NumericalLabel);
|
_centralWidget->setAnalysisMode(CentralWidget::AnalysisMode::NumericalLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionPeakSynthesisAnalysis_triggered() {
|
void MainWindow::on_actionPeakSynthesisAnalysis_triggered()
|
||||||
|
{
|
||||||
_rightWidget->show();
|
_rightWidget->show();
|
||||||
_centralWidget->setAnalysisMode(CentralWidget::AnalysisMode::PeakSynthesisAnalysis);
|
_centralWidget->setAnalysisMode(CentralWidget::AnalysisMode::PeakSynthesisAnalysis);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionClearAllData_triggered() {
|
void MainWindow::on_actionClearAllData_triggered()
|
||||||
|
{
|
||||||
// 实验过程中,不允许清除数据。
|
// 实验过程中,不允许清除数据。
|
||||||
if (Global::_mode == Global::Mode::Experiment) {
|
if (Global::_mode == Global::Mode::Experiment)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -641,62 +727,75 @@ void MainWindow::on_actionClearAllData_triggered() {
|
|||||||
_centralWidget->clearAllData();
|
_centralWidget->clearAllData();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionGlassTransition_triggered() {
|
void MainWindow::on_actionGlassTransition_triggered()
|
||||||
|
{
|
||||||
_rightWidget->show();
|
_rightWidget->show();
|
||||||
_centralWidget->setAnalysisMode(CentralWidget::AnalysisMode::GlassTransition);
|
_centralWidget->setAnalysisMode(CentralWidget::AnalysisMode::GlassTransition);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionOIT_triggered() {
|
void MainWindow::on_actionOIT_triggered()
|
||||||
|
{
|
||||||
_rightWidget->show();
|
_rightWidget->show();
|
||||||
_centralWidget->setAnalysisMode(CentralWidget::AnalysisMode::OIT);
|
_centralWidget->setAnalysisMode(CentralWidget::AnalysisMode::OIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionSpecificHeatCompMethod_triggered() {
|
void MainWindow::on_actionSpecificHeatCompMethod_triggered()
|
||||||
|
{
|
||||||
_specificHeatComparisonMethodForm->show();
|
_specificHeatComparisonMethodForm->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionDegreeOfCrystallinity_triggered() {
|
void MainWindow::on_actionDegreeOfCrystallinity_triggered()
|
||||||
|
{
|
||||||
// QMessageBox::warning(this, "warnning", "结晶度.");
|
// QMessageBox::warning(this, "warnning", "结晶度.");
|
||||||
_degreeOfCrystallinityForm->show();
|
_degreeOfCrystallinityForm->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionInstrumentParameter_triggered() {
|
void MainWindow::on_actionInstrumentParameter_triggered()
|
||||||
|
{
|
||||||
_instrumentCoefficientForm->show();
|
_instrumentCoefficientForm->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_actionOITAutoAnalysisParam_triggered()
|
||||||
void MainWindow::on_actionOITAutoAnalysisParam_triggered() {
|
{
|
||||||
_OITAutoAnalysisParamForm->show();
|
_OITAutoAnalysisParamForm->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionOITAutoAnalysisMode_triggered() {
|
void MainWindow::on_actionOITAutoAnalysisMode_triggered()
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionTimeAxisAnalysisPCTMode_triggered() {
|
void MainWindow::on_actionTimeAxisAnalysisPCTMode_triggered()
|
||||||
|
{
|
||||||
Global::_displayTimeValue = ui->actionTimeAxisAnalysisPCTMode->isChecked();
|
Global::_displayTimeValue = ui->actionTimeAxisAnalysisPCTMode->isChecked();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionDegreeOfCuring_triggered() {
|
void MainWindow::on_actionDegreeOfCuring_triggered()
|
||||||
|
{
|
||||||
//
|
//
|
||||||
_degreeOfCureForm->show();
|
_degreeOfCureForm->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionAbout_triggered() {
|
void MainWindow::on_actionAbout_triggered()
|
||||||
|
{
|
||||||
_aboutForm->show();
|
_aboutForm->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionEnthalpyCorrectionEdit_triggered() {
|
void MainWindow::on_actionEnthalpyCorrectionEdit_triggered()
|
||||||
|
{
|
||||||
_enthalpyDataCorrectionForm->show();
|
_enthalpyDataCorrectionForm->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionEnthalpyCorrectionSelection_triggered() {
|
void MainWindow::on_actionEnthalpyCorrectionSelection_triggered()
|
||||||
|
{
|
||||||
_coefficientSelectionForm->show();
|
_coefficientSelectionForm->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionPrintPreview_triggered() {
|
void MainWindow::on_actionPrintPreview_triggered()
|
||||||
|
{
|
||||||
logde << "print preview...";
|
logde << "print preview...";
|
||||||
|
|
||||||
if (Global::_curveFileDataVtr.empty()) {
|
if (Global::_curveFileDataVtr.empty())
|
||||||
|
{
|
||||||
showMesgBox("请先打开数据。");
|
showMesgBox("请先打开数据。");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -709,100 +808,129 @@ void MainWindow::on_actionPrintPreview_triggered() {
|
|||||||
_printPreviewForm->_customPrintPreviewDialog->update(); // 可选,强制刷新
|
_printPreviewForm->_customPrintPreviewDialog->update(); // 可选,强制刷新
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionOnsetTemperaturePoint_triggered() {
|
void MainWindow::on_actionOnsetTemperaturePoint_triggered()
|
||||||
|
{
|
||||||
_rightWidget->show();
|
_rightWidget->show();
|
||||||
_centralWidget->setAnalysisMode(CentralWidget::AnalysisMode::OnsetTemperaturePoint);
|
_centralWidget->setAnalysisMode(CentralWidget::AnalysisMode::OnsetTemperaturePoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionEndsetTemperaturePoint_triggered() {
|
void MainWindow::on_actionEndsetTemperaturePoint_triggered()
|
||||||
|
{
|
||||||
_rightWidget->show();
|
_rightWidget->show();
|
||||||
_centralWidget->setAnalysisMode(CentralWidget::AnalysisMode::EndsetTemperaturePoint);
|
_centralWidget->setAnalysisMode(CentralWidget::AnalysisMode::EndsetTemperaturePoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionYAxis_triggered() {
|
void MainWindow::on_actionYAxis_triggered()
|
||||||
|
{
|
||||||
_centralWidget->switchAxisMode();
|
_centralWidget->switchAxisMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionAxisSetting_triggered() {
|
void MainWindow::on_actionAxisSetting_triggered()
|
||||||
|
{
|
||||||
_axisSettingForm->show();
|
_axisSettingForm->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionSaveData_triggered() {
|
void MainWindow::on_actionSaveData_triggered()
|
||||||
|
{
|
||||||
QString finaleFileName;
|
QString finaleFileName;
|
||||||
saveFile(Global::_experimentInfo.sampleName, Global::_mode, finaleFileName);
|
saveFile(Global::_experimentInfo.sampleName, Global::_mode, finaleFileName);
|
||||||
_leftWidget->reloadFileName();
|
_leftWidget->reloadFileName();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionSaveas_triggered() {
|
void MainWindow::on_actionSaveas_triggered()
|
||||||
|
{
|
||||||
QString finaleFileName;
|
QString finaleFileName;
|
||||||
saveFile(Global::_experimentInfo.sampleName, Global::Mode::None, finaleFileName);
|
saveFile(Global::_experimentInfo.sampleName, Global::Mode::None, finaleFileName);
|
||||||
_leftWidget->reloadFileName();
|
_leftWidget->reloadFileName();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionLanguage_triggered() {
|
void MainWindow::on_actionLanguage_triggered()
|
||||||
if (Global::_languageType == Global::LanguageType::Chinese) {
|
{
|
||||||
|
if (Global::_languageType == Global::LanguageType::Chinese)
|
||||||
|
{
|
||||||
Global::_languageType = Global::LanguageType::English;
|
Global::_languageType = Global::LanguageType::English;
|
||||||
ui->actionLanguage->setText(Global::EnglishStr);
|
ui->actionLanguage->setText(Global::EnglishStr);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
Global::_languageType = Global::LanguageType::Chinese;
|
Global::_languageType = Global::LanguageType::Chinese;
|
||||||
ui->actionLanguage->setText(Global::ChineseStr);
|
ui->actionLanguage->setText(Global::ChineseStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionSmoothness1_triggered() {
|
void MainWindow::on_actionSmoothness1_triggered()
|
||||||
|
{
|
||||||
smoothness(1);
|
smoothness(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionSmoothness2_triggered() {
|
void MainWindow::on_actionSmoothness2_triggered()
|
||||||
|
{
|
||||||
smoothness(2);
|
smoothness(2);
|
||||||
}
|
}
|
||||||
void MainWindow::on_actionSmoothness3_triggered() {
|
void MainWindow::on_actionSmoothness3_triggered()
|
||||||
|
{
|
||||||
smoothness(3);
|
smoothness(3);
|
||||||
}
|
}
|
||||||
void MainWindow::on_actionSmoothness4_triggered() {
|
void MainWindow::on_actionSmoothness4_triggered()
|
||||||
|
{
|
||||||
smoothness(4);
|
smoothness(4);
|
||||||
}
|
}
|
||||||
void MainWindow::on_actionSmoothness5_triggered() {
|
void MainWindow::on_actionSmoothness5_triggered()
|
||||||
|
{
|
||||||
smoothness(5);
|
smoothness(5);
|
||||||
}
|
}
|
||||||
void MainWindow::on_actionSmoothness6_triggered() {
|
void MainWindow::on_actionSmoothness6_triggered()
|
||||||
|
{
|
||||||
smoothness(6);
|
smoothness(6);
|
||||||
}
|
}
|
||||||
void MainWindow::on_actionSmoothness7_triggered() {
|
void MainWindow::on_actionSmoothness7_triggered()
|
||||||
|
{
|
||||||
smoothness(7);
|
smoothness(7);
|
||||||
}
|
}
|
||||||
void MainWindow::on_actionSmoothness8_triggered() {
|
void MainWindow::on_actionSmoothness8_triggered()
|
||||||
|
{
|
||||||
smoothness(8);
|
smoothness(8);
|
||||||
}
|
}
|
||||||
void MainWindow::on_actionSmoothness9_triggered() {
|
void MainWindow::on_actionSmoothness9_triggered()
|
||||||
|
{
|
||||||
smoothness(9);
|
smoothness(9);
|
||||||
}
|
}
|
||||||
void MainWindow::on_actionSmoothness10_triggered() {
|
void MainWindow::on_actionSmoothness10_triggered()
|
||||||
|
{
|
||||||
smoothness(10);
|
smoothness(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 原始数据
|
// 原始数据
|
||||||
void MainWindow::on_actionOriginalData_triggered() {
|
void MainWindow::on_actionOriginalData_triggered()
|
||||||
if (!Global::_curveExperimentDataVtr.empty()) {
|
{
|
||||||
|
if (!Global::_curveExperimentDataVtr.empty())
|
||||||
|
{
|
||||||
// 删除所有objectName为experiment的curve.
|
// 删除所有objectName为experiment的curve.
|
||||||
_centralWidget->deleteCurveByObjectName(Global::ObjectNameExperiemnt);
|
_centralWidget->deleteCurveByObjectName(Global::ObjectNameExperiemnt);
|
||||||
|
|
||||||
for (auto &item : Global::_curveExperimentDataVtr) {
|
for (auto &item : Global::_curveExperimentDataVtr)
|
||||||
|
{
|
||||||
item.smoothDataVtr.clear();
|
item.smoothDataVtr.clear();
|
||||||
item.curve = _centralWidget->addCurveData(item.dataVtr, Global::ObjectNameExperiemnt);
|
item.curve = _centralWidget->addCurveData(item.dataVtr, Global::ObjectNameExperiemnt);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// 当前数据为文件分析数据时,需要把当前文件下的所有数据都进行平滑处理。
|
// 当前数据为文件分析数据时,需要把当前文件下的所有数据都进行平滑处理。
|
||||||
if(_centralWidget->getCurrentCurve() == nullptr){
|
if (_centralWidget->getCurrentCurve() == nullptr)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString selectedCurveObjectName = _centralWidget->getCurrentCurve()->objectName();
|
QString selectedCurveObjectName = _centralWidget->getCurrentCurve()->objectName();
|
||||||
_centralWidget->deleteCurveByObjectName(selectedCurveObjectName);
|
_centralWidget->deleteCurveByObjectName(selectedCurveObjectName);
|
||||||
|
|
||||||
for (Global::CurveFileData &cfd : Global::_curveFileDataVtr) {
|
for (Global::CurveFileData &cfd : Global::_curveFileDataVtr)
|
||||||
if (selectedCurveObjectName.contains(cfd.filePath)) {
|
{
|
||||||
for (Global::PhaseTotalInfo &pti : cfd.phaseTotalVtr) {
|
if (selectedCurveObjectName.contains(cfd.filePath))
|
||||||
|
{
|
||||||
|
for (Global::PhaseTotalInfo &pti : cfd.phaseTotalVtr)
|
||||||
|
{
|
||||||
pti.smoothDataVtr.clear();
|
pti.smoothDataVtr.clear();
|
||||||
pti.curve = _centralWidget->addCurveData(pti.dataVtr,
|
pti.curve = _centralWidget->addCurveData(pti.dataVtr,
|
||||||
cfd.filePath);
|
cfd.filePath);
|
||||||
@ -847,19 +975,23 @@ void MainWindow::on_actionOriginalData_triggered() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::showMesgBox(const QString str) {
|
void MainWindow::showMesgBox(const QString str)
|
||||||
|
{
|
||||||
static bool isShow = false;
|
static bool isShow = false;
|
||||||
if (!isShow) {
|
if (!isShow)
|
||||||
|
{
|
||||||
isShow = true;
|
isShow = true;
|
||||||
QMessageBox::information(this, "提示", str);
|
QMessageBox::information(this, "提示", str);
|
||||||
isShow = false;
|
isShow = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::slotDeviceDisconnected() {
|
void MainWindow::slotDeviceDisconnected()
|
||||||
|
{
|
||||||
// logde<<"slotDeviceDisconnected...1";
|
// logde<<"slotDeviceDisconnected...1";
|
||||||
// 如果当前是实验模式时,需要先停止实验。
|
// 如果当前是实验模式时,需要先停止实验。
|
||||||
if (SerialPort::instance()->isOpen()) {
|
if (SerialPort::instance()->isOpen())
|
||||||
|
{
|
||||||
// logde<<"slotDeviceDisconnected...2";
|
// logde<<"slotDeviceDisconnected...2";
|
||||||
// ui更新,断开连接
|
// ui更新,断开连接
|
||||||
ui->actionConnectToDev->setIcon(QIcon(":/images/connect.png"));
|
ui->actionConnectToDev->setIcon(QIcon(":/images/connect.png"));
|
||||||
@ -870,3 +1002,17 @@ void MainWindow::slotDeviceDisconnected() {
|
|||||||
SerialPort::instance()->closeSp();
|
SerialPort::instance()->closeSp();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::slotDeleteActionTriggered(const QString &filePath)
|
||||||
|
{
|
||||||
|
logde<<"slotDeleteActionTriggered...1:"<<filePath.toStdString();
|
||||||
|
|
||||||
|
int ret = QMessageBox::question(this,
|
||||||
|
tr("请确认"),
|
||||||
|
tr("确定要删除文件“%1”吗?").arg(filePath),
|
||||||
|
QMessageBox::Ok | QMessageBox::Cancel,
|
||||||
|
QMessageBox::Ok);
|
||||||
|
|
||||||
|
_leftWidget->confirmDelete(ret == QMessageBox::Ok ? true : false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -45,6 +45,9 @@ public slots:
|
|||||||
void slotStartExperiment();
|
void slotStartExperiment();
|
||||||
|
|
||||||
void slotDeviceDisconnected();
|
void slotDeviceDisconnected();
|
||||||
|
|
||||||
|
// 左侧文件管理子窗口操作函数
|
||||||
|
void slotDeleteActionTriggered(const QString&);
|
||||||
protected:
|
protected:
|
||||||
void closeEvent(QCloseEvent *event) override;
|
void closeEvent(QCloseEvent *event) override;
|
||||||
private slots:
|
private slots:
|
||||||
@ -52,6 +55,7 @@ private slots:
|
|||||||
void on_actionConnectToDev_triggered();
|
void on_actionConnectToDev_triggered();
|
||||||
void on_actionNew_triggered();
|
void on_actionNew_triggered();
|
||||||
void on_actionStart_triggered();
|
void on_actionStart_triggered();
|
||||||
|
|
||||||
// 停止实验
|
// 停止实验
|
||||||
void on_actionStop_triggered();
|
void on_actionStop_triggered();
|
||||||
void on_actionReadOnly_triggered();
|
void on_actionReadOnly_triggered();
|
||||||
|
|||||||
@ -1,47 +1,34 @@
|
|||||||
#include <qdir.h>
|
#include <QDir>
|
||||||
#include <qdebug.h>
|
#include <QDebug>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
|
#include <QStyle>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QTreeWidgetItemIterator>
|
||||||
|
#include <QTreeWidget>
|
||||||
|
#include <QTreeWidgetItem>
|
||||||
|
#include <QDirIterator>
|
||||||
|
#include <QMenu>
|
||||||
|
#include <QAction>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QInputDialog>
|
||||||
|
|
||||||
#include "leftwidget.h"
|
#include "leftwidget.h"
|
||||||
#include "filemanager.h"
|
#include "filemanager.h"
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
#include "logger.h"
|
||||||
|
|
||||||
LeftWidget::LeftWidget(QWidget *parent) : QDockWidget(parent) {
|
LeftWidget::LeftWidget(QWidget *parent) : QDockWidget(parent)
|
||||||
|
{
|
||||||
setWindowTitle("文件浏览");
|
setWindowTitle("文件浏览");
|
||||||
|
|
||||||
_treeWidget = new QTreeWidget();
|
_treeWidget = new QTreeWidget();
|
||||||
_treeWidget->setHeaderHidden(true);
|
_treeWidget->setHeaderHidden(true);
|
||||||
|
|
||||||
_sampleDataItem = new QTreeWidgetItem(_treeWidget);
|
|
||||||
_sampleDataItem->setText(0, "样品数据");
|
|
||||||
#if 0
|
|
||||||
_baseLineItem = new QTreeWidgetItem(_treeWidget);
|
|
||||||
_baseLineItem->setText(0,"基线");
|
|
||||||
#endif
|
|
||||||
_analysisStateItem = new QTreeWidgetItem(_treeWidget);
|
|
||||||
_analysisStateItem->setText(0, "分析状态");
|
|
||||||
|
|
||||||
_treeWidget->setSortingEnabled(false);
|
_treeWidget->setSortingEnabled(false);
|
||||||
|
|
||||||
_treeWidget->insertTopLevelItem(0, _sampleDataItem);
|
|
||||||
// _treeWidget->insertTopLevelItem(1, _baseLineItem);
|
|
||||||
_treeWidget->insertTopLevelItem(2, _analysisStateItem);
|
|
||||||
|
|
||||||
setWidget(_treeWidget);
|
setWidget(_treeWidget);
|
||||||
|
|
||||||
// init file name.
|
// 初始化文件树
|
||||||
initFileName(_sampleDataItem, Global::SampleDataFloder);
|
reloadFileTree();
|
||||||
#if 0
|
|
||||||
initFileName(_baseLineItem,Global::BaseLineFolder);
|
|
||||||
#endif
|
|
||||||
initFileName(_analysisStateItem, Global::AnalysisStateFolder);
|
|
||||||
|
|
||||||
expandAll(_sampleDataItem);
|
|
||||||
// expandAll(_baseLineItem);
|
|
||||||
expandAll(_analysisStateItem);
|
|
||||||
|
|
||||||
Global::updateFileList();
|
|
||||||
|
|
||||||
|
|
||||||
// connections
|
// connections
|
||||||
connect(_treeWidget, &QTreeWidget::itemDoubleClicked,
|
connect(_treeWidget, &QTreeWidget::itemDoubleClicked,
|
||||||
@ -49,15 +36,24 @@ LeftWidget::LeftWidget(QWidget *parent) : QDockWidget(parent) {
|
|||||||
|
|
||||||
// 右键菜单
|
// 右键菜单
|
||||||
_contextMenu = new QMenu(_treeWidget);
|
_contextMenu = new QMenu(_treeWidget);
|
||||||
_deleteAction = new QAction("删除", this);
|
_deleteFileAction = new QAction("删除文件", this);
|
||||||
_contextMenu->addAction(_deleteAction);
|
_createFolderAction = new QAction("新建文件夹", this);
|
||||||
|
_contextMenu->addAction(_deleteFileAction);
|
||||||
|
_contextMenu->addAction(_createFolderAction);
|
||||||
|
|
||||||
_treeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
|
_treeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
|
||||||
connect(_treeWidget, &QTreeWidget::customContextMenuRequested,
|
connect(_treeWidget, &QTreeWidget::customContextMenuRequested,
|
||||||
this, &LeftWidget::slotShowContextMenu);
|
this, &LeftWidget::slotShowContextMenu);
|
||||||
|
|
||||||
|
connect(_deleteFileAction, &QAction::triggered,
|
||||||
|
this, &LeftWidget::slotDeleteActionTriggered);
|
||||||
|
connect(_createFolderAction, &QAction::triggered,
|
||||||
|
this, &LeftWidget::slotCreateFolderActionTriggered);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LeftWidget::reloadFileName() {
|
void LeftWidget::reloadFileName()
|
||||||
|
{
|
||||||
clearAllChildItems(_sampleDataItem);
|
clearAllChildItems(_sampleDataItem);
|
||||||
// clearAllChildItems(_baseLineItem);
|
// clearAllChildItems(_baseLineItem);
|
||||||
clearAllChildItems(_analysisStateItem);
|
clearAllChildItems(_analysisStateItem);
|
||||||
@ -66,19 +62,23 @@ void LeftWidget::reloadFileName() {
|
|||||||
#if 0
|
#if 0
|
||||||
initFileName(_baseLineItem,Global::BaseLineFolder);
|
initFileName(_baseLineItem,Global::BaseLineFolder);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
initFileName(_analysisStateItem, Global::AnalysisStateFolder);
|
initFileName(_analysisStateItem, Global::AnalysisStateFolder);
|
||||||
// 更新文件列表
|
// 更新文件列表
|
||||||
Global::updateFileList();
|
Global::updateFileList();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString LeftWidget::filePathCheck(const QString fileName, const QString folderPath) {
|
QString LeftWidget::filePathCheck(const QString fileName, const QString folderPath)
|
||||||
|
{
|
||||||
QString resultFileName = fileName;
|
QString resultFileName = fileName;
|
||||||
|
|
||||||
QDir dir(folderPath);
|
QDir dir(folderPath);
|
||||||
QStringList files = dir.entryList(QDir::Files);
|
QStringList files = dir.entryList(QDir::Files);
|
||||||
for (const QString &existedFileName : files) {
|
for (const QString &existedFileName : files)
|
||||||
|
{
|
||||||
QFileInfo fileInfo(existedFileName);
|
QFileInfo fileInfo(existedFileName);
|
||||||
if (fileName == fileInfo.baseName()) {
|
if (fileName == fileInfo.baseName())
|
||||||
|
{
|
||||||
QDateTime currentDateTime = QDateTime::currentDateTime();
|
QDateTime currentDateTime = QDateTime::currentDateTime();
|
||||||
QString formattedTime = currentDateTime.toString("yyyy_MM_dd_HH_mm_ss");
|
QString formattedTime = currentDateTime.toString("yyyy_MM_dd_HH_mm_ss");
|
||||||
|
|
||||||
@ -90,70 +90,89 @@ QString LeftWidget::filePathCheck(const QString fileName, const QString folderPa
|
|||||||
return resultFileName;
|
return resultFileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LeftWidget::initData() {
|
void LeftWidget::initData()
|
||||||
|
{
|
||||||
// const QString folderPath = QDir::currentPath()+"/../experiment_data";
|
// const QString folderPath = QDir::currentPath()+"/../experiment_data";
|
||||||
const QString folderPath = Global::SampleDataFloder;
|
const QString folderPath = Global::SampleDataFloder;
|
||||||
#if 1
|
#if 1
|
||||||
QDir dir(folderPath);
|
QDir dir(folderPath);
|
||||||
if (!dir.exists()) {
|
if (!dir.exists())
|
||||||
|
{
|
||||||
qWarning() << "文件夹不存在: " << folderPath;
|
qWarning() << "文件夹不存在: " << folderPath;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 遍历文件
|
// 遍历文件
|
||||||
QFileInfoList fileList = dir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot);
|
QFileInfoList fileList = dir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot);
|
||||||
for (const QFileInfo &fileInfo : fileList) {
|
for (const QFileInfo &fileInfo : fileList)
|
||||||
|
{
|
||||||
QFile file(fileInfo.absoluteFilePath());
|
QFile file(fileInfo.absoluteFilePath());
|
||||||
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||||
|
{
|
||||||
QString content = file.readAll();
|
QString content = file.readAll();
|
||||||
qDebug() << "读取文件 " << fileInfo.absoluteFilePath() << " 内容: " << content;
|
qDebug() << "读取文件 " << fileInfo.absoluteFilePath() << " 内容: " << content;
|
||||||
file.close();
|
file.close();
|
||||||
// 写入文件操作示例:这里简单在文件末尾追加一行内容
|
// 写入文件操作示例:这里简单在文件末尾追加一行内容
|
||||||
if (file.open(QIODevice::Append | QIODevice::Text)) {
|
if (file.open(QIODevice::Append | QIODevice::Text))
|
||||||
|
{
|
||||||
file.write("\n这是通过递归写入添加的内容");
|
file.write("\n这是通过递归写入添加的内容");
|
||||||
qDebug() << "已向文件 " << fileInfo.absoluteFilePath() << " 写入内容";
|
qDebug() << "已向文件 " << fileInfo.absoluteFilePath() << " 写入内容";
|
||||||
file.close();
|
file.close();
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
qWarning() << "无法打开文件进行写入: " << fileInfo.absoluteFilePath();
|
qWarning() << "无法打开文件进行写入: " << fileInfo.absoluteFilePath();
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
qWarning() << "无法打开文件进行读取: " << fileInfo.absoluteFilePath();
|
qWarning() << "无法打开文件进行读取: " << fileInfo.absoluteFilePath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#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;
|
||||||
|
|
||||||
if (Global::Mode::Analysis != Global::_mode) {
|
if (Global::Mode::Analysis != Global::_mode)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString fileName;
|
// 检查是否是文件项(有用户数据)
|
||||||
// 获取父节点
|
QVariant userData = item->data(0, Qt::UserRole);
|
||||||
QTreeWidgetItem *parentItem = item->parent();
|
if (userData.isNull() || !userData.isValid())
|
||||||
if (parentItem) {
|
{
|
||||||
qDebug() << "parent item text:" << parentItem->text(0);
|
qDebug() << "点击的是目录项或无效项";
|
||||||
if (parentItem == _sampleDataItem) {
|
|
||||||
fileName = Global::SampleDataFloder + "/" + item->text(0);
|
|
||||||
#if 0
|
|
||||||
}else if(parentItem == _baseLineItem){
|
|
||||||
fileName =Global::BaseLineFolder + "/" +item->text(0);
|
|
||||||
#endif
|
|
||||||
} else if (parentItem == _analysisStateItem) {
|
|
||||||
fileName = Global::AnalysisStateFolder + "/" + item->text(0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
qDebug() << "item has no parent (it is a top-level item)";
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
emit sigSendAnalysisFileName(fileName);
|
QString filePath = userData.toString();
|
||||||
|
if (filePath.isEmpty())
|
||||||
|
{
|
||||||
|
qDebug() << "文件路径为空";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
void LeftWidget::initFileName(QTreeWidgetItem *parentItem, const QString &folderPath) {
|
|
||||||
|
// 检查文件是否存在
|
||||||
|
QFileInfo fileInfo(filePath);
|
||||||
|
if (!fileInfo.exists())
|
||||||
|
{
|
||||||
|
qWarning() << "文件不存在: " << filePath;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送文件路径信号
|
||||||
|
emit sigSendAnalysisFileName(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LeftWidget::initFileName(QTreeWidgetItem *parentItem, const QString &folderPath)
|
||||||
|
{
|
||||||
QDir dir(folderPath);
|
QDir dir(folderPath);
|
||||||
QStringList files = dir.entryList(QDir::Files);
|
QStringList files = dir.entryList(QDir::Files);
|
||||||
for (const QString &fileName : files) {
|
for (const QString &fileName : files)
|
||||||
|
{
|
||||||
QTreeWidgetItem *subItem = new QTreeWidgetItem();
|
QTreeWidgetItem *subItem = new QTreeWidgetItem();
|
||||||
subItem->setText(0, fileName);
|
subItem->setText(0, fileName);
|
||||||
subItem->setData(0, Qt::UserRole, QVariant::fromValue(folderPath + "/" + fileName));
|
subItem->setData(0, Qt::UserRole, QVariant::fromValue(folderPath + "/" + fileName));
|
||||||
@ -161,22 +180,25 @@ void LeftWidget::initFileName(QTreeWidgetItem *parentItem, const QString &folder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LeftWidget::expandAll(QTreeWidgetItem *item) {
|
void LeftWidget::expandAll(QTreeWidgetItem *item)
|
||||||
|
{
|
||||||
item->setExpanded(true);
|
item->setExpanded(true);
|
||||||
for (int i = 0; i < item->childCount(); ++i) {
|
for (int i = 0; i < item->childCount(); ++i)
|
||||||
|
{
|
||||||
expandAll(item->child(i));
|
expandAll(item->child(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LeftWidget::clearAllChildItems(QTreeWidgetItem *parentItem) {
|
void LeftWidget::clearAllChildItems(QTreeWidgetItem *parentItem)
|
||||||
|
{
|
||||||
int childCount = parentItem->childCount();
|
int childCount = parentItem->childCount();
|
||||||
for (int i = 0; i < childCount; ++i) {
|
for (int i = 0; i < childCount; ++i)
|
||||||
|
{
|
||||||
QTreeWidgetItem *childItem = parentItem->takeChild(0);
|
QTreeWidgetItem *childItem = parentItem->takeChild(0);
|
||||||
delete childItem;
|
delete childItem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
void LeftWidget::recursiveFolderOperation(const QString& folderPath) {
|
void LeftWidget::recursiveFolderOperation(const QString& folderPath) {
|
||||||
QDir dir(folderPath);
|
QDir dir(folderPath);
|
||||||
@ -215,26 +237,334 @@ void LeftWidget::recursiveFolderOperation(const QString& folderPath) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void LeftWidget::slotShowContextMenu(const QPoint &pos) {
|
void LeftWidget::slotShowContextMenu(const QPoint &pos)
|
||||||
QPoint globalPos = _treeWidget->mapToGlobal(pos);
|
{
|
||||||
_contextMenu->exec(globalPos);
|
QTreeWidgetItem *item = _treeWidget->itemAt(pos);
|
||||||
|
if (item) {
|
||||||
|
// 获取文件路径
|
||||||
|
QString filePath = item->data(0, Qt::UserRole).toString();
|
||||||
|
QString dirPath = item->data(0, Qt::UserRole + 1).toString();
|
||||||
|
|
||||||
// 获取当前选中的项
|
// 如果是文件
|
||||||
QTreeWidgetItem *currentItem = _treeWidget->itemAt(pos);
|
if (!filePath.isEmpty()) {
|
||||||
if (currentItem == nullptr) {
|
_deleteFileActionFilePath = filePath;
|
||||||
return;
|
_deleteFileAction->setVisible(true);
|
||||||
|
_deleteFileAction->setText(tr("删除文件"));
|
||||||
}
|
}
|
||||||
|
// 如果是目录
|
||||||
QString filePath = currentItem->data(0, Qt::UserRole).toString();
|
else if (!dirPath.isEmpty()) {
|
||||||
if (filePath.isEmpty()) {
|
// 暂时不要删除文件件功能
|
||||||
return;
|
_deleteFileAction->setVisible(false);
|
||||||
}
|
#if 0
|
||||||
// qDebug() << "file:" << filePath;
|
_deleteFileAction->setVisible(true);
|
||||||
if (QFile::remove(filePath)) {
|
_deleteFileActionFilePath = dirPath;
|
||||||
qDebug() << "文件删除成功:" << filePath;
|
_deleteFileAction->setText(tr("删除文件夹"));
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
qWarning() << "文件删除失败:" << filePath;
|
_deleteFileAction->setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
reloadFileName();
|
// 只有当点击的是目录时才显示"新建文件夹"选项
|
||||||
|
bool isDir = !dirPath.isEmpty();
|
||||||
|
_createFolderAction->setVisible(isDir);
|
||||||
|
|
||||||
|
_contextMenu->exec(_treeWidget->mapToGlobal(pos));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LeftWidget::slotDeleteActionTriggered()
|
||||||
|
{
|
||||||
|
if (_deleteFileActionFilePath.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QFileInfo fileInfo(_deleteFileActionFilePath);
|
||||||
|
bool isDir = fileInfo.isDir();
|
||||||
|
|
||||||
|
// 检查文件/目录是否存在
|
||||||
|
if (!fileInfo.exists()) {
|
||||||
|
QMessageBox::warning(this, tr("警告"), tr("文件/目录不存在!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确认删除对话框
|
||||||
|
int ret = QMessageBox::question(this, tr("确认删除"),
|
||||||
|
tr("确定要删除%1\n%2?").arg(isDir ? tr("文件夹及其所有内容") : tr("文件")).arg(_deleteFileActionFilePath),
|
||||||
|
QMessageBox::Yes | QMessageBox::No,
|
||||||
|
QMessageBox::No);
|
||||||
|
|
||||||
|
if (ret == QMessageBox::Yes) {
|
||||||
|
bool success;
|
||||||
|
if (isDir) {
|
||||||
|
// 删除目录及其内容
|
||||||
|
success = removeDir(_deleteFileActionFilePath);
|
||||||
|
} else {
|
||||||
|
// 删除文件
|
||||||
|
success = QFile::remove(_deleteFileActionFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
// 重新加载文件树
|
||||||
|
reloadFileTree();
|
||||||
|
} else {
|
||||||
|
QMessageBox::critical(this, tr("错误"), tr("删除失败!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_deleteFileActionFilePath.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
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()) {
|
||||||
|
result = removeDir(info.absoluteFilePath());
|
||||||
|
} else {
|
||||||
|
result = QFile::remove(info.absoluteFilePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result = dir.rmdir(dirPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LeftWidget::slotCreateFolderActionTriggered()
|
||||||
|
{
|
||||||
|
// 获取当前选中的项目
|
||||||
|
QTreeWidgetItem *currentItem = _treeWidget->currentItem();
|
||||||
|
if (!currentItem) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当前目录路径
|
||||||
|
QString dirPath;
|
||||||
|
if (currentItem->data(0, Qt::UserRole + 1).toString().isEmpty()) {
|
||||||
|
// 如果是文件,获取其父目录
|
||||||
|
dirPath = QFileInfo(currentItem->data(0, Qt::UserRole).toString()).absolutePath();
|
||||||
|
} else {
|
||||||
|
// 如果是目录,直接使用其路径
|
||||||
|
dirPath = currentItem->data(0, Qt::UserRole + 1).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 弹出对话框,输入新文件夹名称
|
||||||
|
bool ok;
|
||||||
|
QString folderName = QInputDialog::getText(this, tr("新建文件夹"),
|
||||||
|
tr("请输入文件夹名称:"),
|
||||||
|
QLineEdit::Normal,
|
||||||
|
tr("新建文件夹"), &ok);
|
||||||
|
|
||||||
|
if (!ok || folderName.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查文件夹名称是否有效
|
||||||
|
if (folderName.contains(QRegExp("[\\/:*?\"<>|]"))) {
|
||||||
|
QMessageBox::warning(this, tr("错误"), tr("文件夹名称包含非法字符!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建新文件夹路径
|
||||||
|
QString newFolderPath = dirPath + "/" + folderName;
|
||||||
|
|
||||||
|
// 检查文件夹是否已存在
|
||||||
|
if (QDir(newFolderPath).exists()) {
|
||||||
|
QMessageBox::warning(this, tr("错误"), tr("文件夹已存在!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建文件夹
|
||||||
|
if (QDir().mkdir(newFolderPath)) {
|
||||||
|
// 保存当前展开状态
|
||||||
|
saveExpandedState();
|
||||||
|
|
||||||
|
// 重新加载文件树
|
||||||
|
reloadFileTree();
|
||||||
|
|
||||||
|
// 恢复展开状态
|
||||||
|
restoreExpandedState();
|
||||||
|
|
||||||
|
// 展开当前目录并选中新创建的文件夹
|
||||||
|
expandAndSelectItem(newFolderPath);
|
||||||
|
} else {
|
||||||
|
QMessageBox::critical(this, tr("错误"), tr("创建文件夹失败!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LeftWidget::expandAndSelectItem(const QString &path)
|
||||||
|
{
|
||||||
|
// 递归展开到指定路径并选中该项
|
||||||
|
QTreeWidgetItemIterator it(_treeWidget);
|
||||||
|
while (*it) {
|
||||||
|
QTreeWidgetItem *item = *it;
|
||||||
|
QString itemPath = item->data(0, Qt::UserRole + 1).toString();
|
||||||
|
|
||||||
|
if (itemPath == path) {
|
||||||
|
// 展开所有父节点
|
||||||
|
QTreeWidgetItem *parent = item->parent();
|
||||||
|
while (parent) {
|
||||||
|
parent->setExpanded(true);
|
||||||
|
parent = parent->parent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选中新创建的文件夹
|
||||||
|
_treeWidget->setCurrentItem(item);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LeftWidget::confirmDelete(bool enabled)
|
||||||
|
{
|
||||||
|
if (enabled)
|
||||||
|
{
|
||||||
|
if (QFile::remove(_deleteFileActionFilePath))
|
||||||
|
{
|
||||||
|
// qDebug() << "文件删除成功:" << filePath;
|
||||||
|
logde << "delete succ:" << _deleteFileActionFilePath.toStdString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// qWarning() << "文件删除失败:" << filePath;
|
||||||
|
logde << "delete fail:" << _deleteFileActionFilePath.toStdString();
|
||||||
|
}
|
||||||
|
// 重新加载文件树
|
||||||
|
reloadFileTree();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LeftWidget::reloadFileTree()
|
||||||
|
{
|
||||||
|
// 保存当前展开状态
|
||||||
|
saveExpandedState();
|
||||||
|
|
||||||
|
// 清空现有的树形结构
|
||||||
|
_treeWidget->clear();
|
||||||
|
|
||||||
|
// 创建根节点
|
||||||
|
QTreeWidgetItem *rootItem = new QTreeWidgetItem(_treeWidget);
|
||||||
|
rootItem->setText(0, "实验数据");
|
||||||
|
rootItem->setData(0, Qt::UserRole, Global::ExperimentDirPath);
|
||||||
|
// 保存根目录路径,用于恢复展开状态
|
||||||
|
rootItem->setData(0, Qt::UserRole + 1, Global::ExperimentDirPath);
|
||||||
|
|
||||||
|
// 递归扫描目录并构建树形结构
|
||||||
|
buildFileTree(rootItem, Global::ExperimentDirPath);
|
||||||
|
|
||||||
|
// 展开根节点
|
||||||
|
rootItem->setExpanded(true);
|
||||||
|
|
||||||
|
// 恢复展开状态
|
||||||
|
restoreExpandedState();
|
||||||
|
|
||||||
|
// 更新全局文件列表
|
||||||
|
Global::updateFileList();
|
||||||
|
}
|
||||||
|
|
||||||
|
QFileInfoList LeftWidget::scanDirRecursively(const QString &rootPath)
|
||||||
|
{
|
||||||
|
QFileInfoList result; // 1. 结果容器
|
||||||
|
QDirIterator it(rootPath, // 2. 迭代器:从 rootPath 开始
|
||||||
|
QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot, // 3. 要哪些条目
|
||||||
|
QDirIterator::Subdirectories); // 4. 递归标志
|
||||||
|
while (it.hasNext())
|
||||||
|
{ // 5. 还有下一条吗?
|
||||||
|
it.next(); // 6. 推进到下一个条目
|
||||||
|
result.append(it.fileInfo()); // 7. 把当前条目塞进列表
|
||||||
|
}
|
||||||
|
return result; // 8. 返回
|
||||||
|
}
|
||||||
|
|
||||||
|
void LeftWidget::buildFileTree(QTreeWidgetItem *parentItem, const QString &dirPath)
|
||||||
|
{
|
||||||
|
QDir dir(dirPath);
|
||||||
|
if (!dir.exists()) {
|
||||||
|
qWarning() << "目录不存在: " << dirPath;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取所有子目录和文件,按名称排序
|
||||||
|
dir.setSorting(QDir::Name | QDir::DirsFirst);
|
||||||
|
QFileInfoList list = dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
|
||||||
|
|
||||||
|
for (const QFileInfo &fileInfo : list) {
|
||||||
|
QTreeWidgetItem *item = new QTreeWidgetItem(parentItem);
|
||||||
|
|
||||||
|
if (fileInfo.isDir()) {
|
||||||
|
// 设置目录项
|
||||||
|
item->setText(0, fileInfo.fileName());
|
||||||
|
// 使用系统默认的目录图标
|
||||||
|
item->setIcon(0, _treeWidget->style()->standardIcon(QStyle::SP_DirIcon));
|
||||||
|
// 保存目录路径,用于恢复展开状态
|
||||||
|
item->setData(0, Qt::UserRole + 1, fileInfo.absoluteFilePath());
|
||||||
|
|
||||||
|
// 递归处理子目录
|
||||||
|
buildFileTree(item, fileInfo.absoluteFilePath());
|
||||||
|
} else {
|
||||||
|
// 设置文件项
|
||||||
|
item->setText(0, fileInfo.fileName());
|
||||||
|
item->setData(0, Qt::UserRole, fileInfo.absoluteFilePath());
|
||||||
|
|
||||||
|
// 根据文件类型设置不同的图标
|
||||||
|
QString suffix = fileInfo.suffix().toLower();
|
||||||
|
if (suffix == "xlsx" || suffix == "xls") {
|
||||||
|
// 使用系统默认的文档图标
|
||||||
|
item->setIcon(0, _treeWidget->style()->standardIcon(QStyle::SP_FileIcon));
|
||||||
|
} else {
|
||||||
|
// 使用默认文件图标
|
||||||
|
item->setIcon(0, _treeWidget->style()->standardIcon(QStyle::SP_FileIcon));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LeftWidget::saveExpandedState()
|
||||||
|
{
|
||||||
|
_expandedPaths.clear();
|
||||||
|
|
||||||
|
// 递归遍历所有项,保存展开的目录路径
|
||||||
|
QTreeWidgetItemIterator it(_treeWidget);
|
||||||
|
while (*it) {
|
||||||
|
QTreeWidgetItem *item = *it;
|
||||||
|
if (item->isExpanded()) {
|
||||||
|
QVariant pathData = item->data(0, Qt::UserRole + 1);
|
||||||
|
if (!pathData.isNull()) {
|
||||||
|
_expandedPaths.append(pathData.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "保存了" << _expandedPaths.size() << "个展开状态:" << _expandedPaths;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LeftWidget::restoreExpandedState()
|
||||||
|
{
|
||||||
|
int restoredCount = 0;
|
||||||
|
|
||||||
|
// 递归遍历所有项,恢复展开状态
|
||||||
|
QTreeWidgetItemIterator it(_treeWidget);
|
||||||
|
while (*it) {
|
||||||
|
QTreeWidgetItem *item = *it;
|
||||||
|
QVariant pathData = item->data(0, Qt::UserRole + 1);
|
||||||
|
if (!pathData.isNull()) {
|
||||||
|
QString path = pathData.toString();
|
||||||
|
if (_expandedPaths.contains(path)) {
|
||||||
|
item->setExpanded(true);
|
||||||
|
restoredCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "恢复了" << restoredCount << "个展开状态";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,18 +19,30 @@ public:
|
|||||||
|
|
||||||
void reloadFileName();
|
void reloadFileName();
|
||||||
|
|
||||||
|
void reloadFileTree();
|
||||||
|
|
||||||
QString filePathCheck(const QString fileName,const QString folderPath);
|
QString filePathCheck(const QString fileName,const QString folderPath);
|
||||||
|
// 确认删除文件
|
||||||
|
void confirmDelete(bool enabled);
|
||||||
signals:
|
signals:
|
||||||
void sigSendAnalysisFileName(const QString&);
|
void sigSendAnalysisFileName(const QString&);
|
||||||
|
void sigDeleteActionTriggered(const QString&);
|
||||||
private:
|
private:
|
||||||
void initData();
|
void initData();
|
||||||
void initFileName(QTreeWidgetItem*,const QString &folderPath);
|
void initFileName(QTreeWidgetItem*,const QString &folderPath);
|
||||||
void expandAll(QTreeWidgetItem* item);
|
void expandAll(QTreeWidgetItem* item);
|
||||||
void clearAllChildItems(QTreeWidgetItem* parentItem);
|
void clearAllChildItems(QTreeWidgetItem* parentItem);
|
||||||
void removeFile(const QString& filePath);
|
QFileInfoList scanDirRecursively(const QString &rootPath);
|
||||||
|
void buildFileTree(QTreeWidgetItem *parentItem, const QString &dirPath);
|
||||||
|
void saveExpandedState();
|
||||||
|
void restoreExpandedState();
|
||||||
|
void expandAndSelectItem(const QString &path);
|
||||||
|
bool removeDir(const QString &dirPath);
|
||||||
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 slotCreateFolderActionTriggered();
|
||||||
private:
|
private:
|
||||||
QTreeWidget *_treeWidget;
|
QTreeWidget *_treeWidget;
|
||||||
|
|
||||||
@ -39,7 +51,14 @@ private:
|
|||||||
*_sampleDataItem;
|
*_sampleDataItem;
|
||||||
|
|
||||||
QMenu *_contextMenu;
|
QMenu *_contextMenu;
|
||||||
QAction *_deleteAction;
|
|
||||||
|
QAction *_deleteFileAction;
|
||||||
|
QAction *_createFolderAction;
|
||||||
|
QString _deleteFileActionFilePath;
|
||||||
|
|
||||||
|
// 保存展开状态的列表
|
||||||
|
QStringList _expandedPaths;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LEFTWIDGET_H
|
#endif // LEFTWIDGET_H
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user