#include "nmWxDFNLoadFromFile.h" #include #include #include #include #include #include #include #include #include "nmDataAnalyzeManager.h" #include "nmDataFracture.h" #include "nmGuiPlot.h" #include "nmObjLineCrack.h" #include "ZxPlot.h" #include "ExcelUtils.h" // 构造函数 nmWxDFNLoadFromFile::nmWxDFNLoadFromFile(QWidget* pParent) : QDialog(pParent) { this->setWindowTitle(tr("Load from file...")); this->setMinimumSize(861, 708); QString appDir = QCoreApplication::applicationDirPath(); appDir = appDir.section('/', 0, -2); // 获取上一级目录 m_sLastOpenedFilePath = appDir + "/Temp/DFN"; this->initUI(); this->initConnections(); // 初始化Type到Unit的映射 this->initUnitMappings(); this->setupTable(); } nmWxDFNLoadFromFile::~nmWxDFNLoadFromFile() { // 所有Qt对象会自动被父对象删除 } void nmWxDFNLoadFromFile::initUI() { QVBoxLayout* pMainLayout = new QVBoxLayout(this); // 创建水平布局容器 QHBoxLayout* pTopHorizontalLayout = new QHBoxLayout(); // 1. 数据源部分 m_pSourceGroup = new QGroupBox(tr("Data Source"), this); m_pSourceGroup->setFixedSize(337, 106); // 使用垂直布局作为主布局(包含按钮行和文件路径行) QVBoxLayout* pSourceMainLayout = new QVBoxLayout(m_pSourceGroup); // 1.1 导入文件按钮部分(水平布局) QHBoxLayout* pLoadButtonLayout = new QHBoxLayout(); m_pLoadTxtButton = new QPushButton(this); m_pLoadExcelButton = new QPushButton(this); m_pCopyButton = new QPushButton(this); QString appDir = QCoreApplication::applicationDirPath(); appDir = appDir.section('/', 0, -2); // 获取上一级目录 // 设置按钮图标 QIcon loadTXTIcon(appDir + "/Res/Icon/NmDFNLoadTXT.png"); QIcon loadExcelIcon(appDir + "/Res/Icon/NmDFNLoadExcel.png"); QIcon loadCopyIcon(appDir + "/Res/Icon/NmDFNLoadCopy.png"); m_pLoadTxtButton->setIcon(loadTXTIcon); m_pLoadExcelButton->setIcon(loadExcelIcon); m_pCopyButton->setIcon(loadCopyIcon); // 设置图标大小 int iconSize = 32; m_pLoadTxtButton->setIconSize(QSize(iconSize, iconSize)); m_pLoadExcelButton->setIconSize(QSize(iconSize, iconSize)); m_pCopyButton->setIconSize(QSize(iconSize, iconSize)); int iButtonWidth = 88; int iButtonHeight = 41; m_pLoadTxtButton->setFixedSize(iButtonWidth, iButtonHeight); m_pLoadExcelButton->setFixedSize(iButtonWidth, iButtonHeight); m_pCopyButton->setFixedSize(iButtonWidth, iButtonHeight); pLoadButtonLayout->addWidget(m_pLoadTxtButton); pLoadButtonLayout->addWidget(m_pLoadExcelButton); pLoadButtonLayout->addWidget(m_pCopyButton); pLoadButtonLayout->addStretch(); // 1.2 文件路径部分(水平布局) QHBoxLayout* pFilePathLayout = new QHBoxLayout(); m_pFilePathEdit = new QLineEdit(this); m_pBrowseButton = new QPushButton("...", this); m_pBrowseButton->setFixedWidth(30); // 固定宽度 pFilePathLayout->addWidget(m_pFilePathEdit); pFilePathLayout->addWidget(m_pBrowseButton); // 将两个水平布局添加到垂直主布局(按钮在上,文件路径在下) pSourceMainLayout->addLayout(pLoadButtonLayout); pSourceMainLayout->addLayout(pFilePathLayout); pTopHorizontalLayout->addWidget(m_pSourceGroup); // 2. 分隔符部分 m_pSeparatorGroup = new QGroupBox(tr("Separators"), this); m_pSeparatorGroup->setFixedSize(233,106); // 固定大小 // 使用复选框代替单选按钮 m_pSpaceCheck = new QCheckBox(tr("Space"), this); m_pTabCheck = new QCheckBox(tr("Tab"), this); m_pOtherLabel = new QLabel(tr("Others:"),this); // 默认全部启用 m_pSpaceCheck->setChecked(true); m_pTabCheck->setChecked(true); m_pOtherSeparatorEdit = new QLineEdit(this); m_pOtherSeparatorEdit->setMaximumWidth(50); m_pOtherSeparatorEdit->setText(";"); // 默认自定义分隔符为分号 QVBoxLayout* pSepLayout = new QVBoxLayout(m_pSeparatorGroup); pSepLayout->addWidget(m_pSpaceCheck); pSepLayout->addWidget(m_pTabCheck); QHBoxLayout* pOtherLayout = new QHBoxLayout(); pOtherLayout->addWidget(m_pOtherLabel); pOtherLayout->addWidget(m_pOtherSeparatorEdit); pOtherLayout->addStretch(); pSepLayout->addLayout(pOtherLayout); pTopHorizontalLayout->addWidget(m_pSeparatorGroup); // 3. 信息提示 - 现在放在GroupBox中 m_pInfoGroup = new QGroupBox(tr("Info"), this); m_pInfoGroup->setFixedSize(255,106); // 固定大小 m_pInfoLabel = new QLabel( tr("You need to assign at least 4 required types: X1, Y1, X2, Y2."), this); m_pInfoLabel->setWordWrap(true); m_pInfoLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); QVBoxLayout* pInfoLayout = new QVBoxLayout(m_pInfoGroup); pInfoLayout->addWidget(m_pInfoLabel); pTopHorizontalLayout->addWidget(m_pInfoGroup); pTopHorizontalLayout->addStretch(); // 将水平布局添加到主布局 pMainLayout->addLayout(pTopHorizontalLayout); // 4. 列类型分配表格 QWidget* pTableContainer = new QWidget(this); QHBoxLayout* pTableLayout = new QHBoxLayout(pTableContainer); pTableLayout->setContentsMargins(0, 0, 0, 0); // 去掉布局边距 m_pColumnTable = new QTableWidget(); m_pColumnTable->setStyleSheet("border: none;"); // 去掉表格的边框 pTableLayout->addWidget(m_pColumnTable); //pTableLayout->addStretch(); // 设置容器的边框样式 pTableContainer->setStyleSheet("border: 1px solid #d3d3d3;"); pMainLayout->addWidget(pTableContainer); // 5. 按钮区域 QHBoxLayout* pButtonLayout = new QHBoxLayout(); m_pOkButton = new QPushButton(tr("OK"), this); m_pCancelButton = new QPushButton(tr("Cancel"), this); pButtonLayout->addStretch(); pButtonLayout->addWidget(m_pOkButton); pButtonLayout->addWidget(m_pCancelButton); pMainLayout->addLayout(pButtonLayout); } void nmWxDFNLoadFromFile::initConnections() { connect(m_pOkButton, SIGNAL(clicked()), this, SLOT(onOkClicked())); connect(m_pCancelButton, SIGNAL(clicked()), this, SLOT(onCancelClicked())); connect(m_pLoadTxtButton, SIGNAL(clicked()), this, SLOT(onLoadTxtClicked())); connect(m_pLoadExcelButton, SIGNAL(clicked()), this, SLOT(onLoadExcelClicked())); connect(m_pBrowseButton, SIGNAL(clicked()), this, SLOT(onBrowseClicked())); connect(m_pColumnTable, SIGNAL(cellClicked(int, int)), this, SLOT(onTableClicked(int, int))); connect(m_pColumnTable, SIGNAL(cellChanged(int, int)), this, SLOT(onCellChanged(int, int))); // 添加分隔符复选框的信号连接 connect(m_pSpaceCheck, SIGNAL(stateChanged(int)), this, SLOT(updateSeparators())); connect(m_pTabCheck, SIGNAL(stateChanged(int)), this, SLOT(updateSeparators())); connect(m_pOtherSeparatorEdit, SIGNAL(textChanged(QString)), this, SLOT(updateSeparators())); } void nmWxDFNLoadFromFile::initUnitMappings() { // 设置Type到单位选项的映射 m_typeToUnitOptions["X1"] = QStringList() << "cm" << "mm" << "m" << "0.1in" << "ft" << "mile"; m_typeToUnitOptions["Y1"] = QStringList() << "cm" << "mm" << "m" << "0.1in" << "ft" << "mile"; m_typeToUnitOptions["X2"] = QStringList() << "cm" << "mm" << "m" << "0.1in" << "ft" << "mile"; m_typeToUnitOptions["Y2"] = QStringList() << "cm" << "mm" << "m" << "0.1in" << "ft" << "mile"; m_typeToUnitOptions["Wf"] = QStringList() << "cm" << "mm" << "m" << "0.1in" << "ft" << "mile"; m_typeToUnitOptions["Fc"] = QStringList() << "md.ft" << "md.m" << "m^3"; m_typeToUnitOptions["o"] = QStringList(); // 空选项 m_typeToUnitOptions["UnDefined"] = QStringList(); // 空选项 // 设置Type到默认单位的映射 m_typeToDefaultUnit["X1"] = "m"; m_typeToDefaultUnit["Y1"] = "m"; m_typeToDefaultUnit["X2"] = "m"; m_typeToDefaultUnit["Y2"] = "m"; m_typeToDefaultUnit["Wf"] = "m"; m_typeToDefaultUnit["Fc"] = "md.m"; m_typeToDefaultUnit["o"] = ""; // 空 m_typeToDefaultUnit["UnDefined"] = ""; // 空 // 按顺序设置所有Type选项 m_allTypeOptions << "X1" << "Y1" << "X2" << "Y2" << "Fc" << "Wf" << "o" << "UnDefined"; } void nmWxDFNLoadFromFile::setupTable() { // 设置表格为3行0列(只有表头行,没有数据列) m_pColumnTable->setRowCount(3); // Column, Type, Unit m_pColumnTable->setColumnCount(0); // 初始没有列 // 设置垂直表头 QStringList verticalHeaders; verticalHeaders << "Column" << "Type" << "Unit"; m_pColumnTable->setVerticalHeaderLabels(verticalHeaders); // 设置表头样式 QHeaderView* verticalHeader = m_pColumnTable->verticalHeader(); QHeaderView* horizontalHeader = m_pColumnTable->horizontalHeader(); verticalHeader->setVisible(true); horizontalHeader->setVisible(false); // 关键修复:确保在设置数据前应用尺寸 verticalHeader->setMinimumSectionSize(20); // 行高 horizontalHeader->setMinimumSectionSize(100); // 列宽 // 锁定尺寸策略 m_pColumnTable->verticalHeader()->setResizeMode(QHeaderView::Fixed); m_pColumnTable->horizontalHeader()->setResizeMode(QHeaderView::Fixed); m_pColumnTable->verticalHeader()->setDefaultAlignment(Qt::AlignCenter); m_pColumnTable->horizontalHeader()->setDefaultAlignment(Qt::AlignCenter); // 设置默认行高 //m_pColumnTable->verticalHeader()->setDefaultSectionSize(25); } void nmWxDFNLoadFromFile::onLoadTxtClicked() { QString filePath = QFileDialog::getOpenFileName( this, tr("Open Text File"), m_sLastOpenedFilePath, tr("Text Files (*.txt);;All Files (*)") ); if (filePath.isEmpty()) { return; } // 检查文件扩展名 if (!filePath.endsWith(".txt", Qt::CaseInsensitive)) { QMessageBox::warning(this, tr("Error"), tr("Please select a text file (.txt)")); return; } m_sLastOpenedFilePath = filePath; m_pFilePathEdit->setText(filePath); // 读取文件内容 QStringList lines = readFileContent(filePath); if (lines.isEmpty()) { return; } // 解析内容 QRegExp separatorRegex = buildSeparatorRegex(); QList parsedData; for (int i = 0; i < lines.size(); ++i) { parsedData << lines[i].split(separatorRegex, QString::SkipEmptyParts); } // 处理数据 clearDataRows(); setupTableColumns(parsedData.isEmpty() ? 0 : parsedData[0].size()); populateDataRows(parsedData); } void nmWxDFNLoadFromFile::onLoadExcelClicked() { QString filePath = QFileDialog::getOpenFileName( this, tr("Open Excel File"), m_sLastOpenedFilePath, tr("Excel Files (*.xls *.xlsx);;All Files (*)") ); if (filePath.isEmpty()) { return; } // 检查文件扩展名 if (!filePath.endsWith(".xls", Qt::CaseInsensitive) && !filePath.endsWith(".xlsx", Qt::CaseInsensitive)) { QMessageBox::warning(this, tr("Error"), tr("Please select an Excel file (.xls or .xlsx)")); return; } m_sLastOpenedFilePath = filePath; m_pFilePathEdit->setText(filePath); // 解析Excel数据 QList excelData = parseExcelData(filePath); if (excelData.isEmpty()) { return; } // 处理数据 clearDataRows(); setupTableColumns(excelData.isEmpty() ? 0 : excelData[0].size()); populateDataRows(excelData); } void nmWxDFNLoadFromFile::onBrowseClicked() { QString filePath = QFileDialog::getOpenFileName( this, tr("Open Text File"), m_sLastOpenedFilePath, tr("Text Files (*.txt);;All Files (*)") ); if (filePath.isEmpty()) { return; } // 检查文件扩展名 if (!filePath.endsWith(".txt", Qt::CaseInsensitive)) { QMessageBox::warning(this, tr("Error"), tr("Please select a text file (.txt)")); return; } m_sLastOpenedFilePath = filePath; m_pFilePathEdit->setText(filePath); // 读取文件内容 QStringList lines = readFileContent(filePath); if (lines.isEmpty()) { return; } // 解析内容 QRegExp separatorRegex = buildSeparatorRegex(); QList parsedData; for (int i = 0; i < lines.size(); ++i) { parsedData << lines[i].split(separatorRegex, QString::SkipEmptyParts); } // 处理数据 clearDataRows(); setupTableColumns(parsedData.isEmpty() ? 0 : parsedData[0].size()); populateDataRows(parsedData); } void nmWxDFNLoadFromFile::onTableClicked(int row, int col) { // 先检查是否有未关闭的下拉框,并保存值 closeOpenComboBox(); // 仅处理Type行(1)和Unit行(2) if (row != 1 && row != 2) return; // 获取当前单元格的文本 QTableWidgetItem* item = m_pColumnTable->item(row, col); if (!item) return; QString currentText = item->text(); // 移除可能已存在的单元格控件(确保是QComboBox类型) QComboBox* existingCombo = qobject_cast(m_pColumnTable->cellWidget(row, col)); if (existingCombo) { disconnect(existingCombo, 0, this, 0); // 断开原有信号连接 delete existingCombo; } // 创建下拉框 QComboBox* comboBox = new QComboBox(); // 根据行设置不同的选项 if (row == 1) { // Type行 comboBox->addItems(m_allTypeOptions); } else { // Unit行 - 根据Type动态生成选项 // 获取当前列的Type值 QTableWidgetItem* typeItem = m_pColumnTable->item(1, col); QString typeValue = typeItem ? typeItem->text() : "UnDefined"; // 获取对应的单位选项列表 QStringList unitOptions = m_typeToUnitOptions.value(typeValue); comboBox->addItems(unitOptions); // 如果Unit为空,设置默认值 if (currentText.isEmpty()) { QString defaultUnit = m_typeToDefaultUnit.value(typeValue); int defaultIndex = comboBox->findText(defaultUnit); if (defaultIndex >= 0) { comboBox->setCurrentIndex(defaultIndex); // 同时更新表格中的Unit值 item->setText(defaultUnit); } } } // 设置当前选中项(兼容Qt 4) int index = comboBox->findText(currentText); if (index >= 0) { comboBox->setCurrentIndex(index); } // 设置样式并添加到单元格 comboBox->setStyleSheet("text-align: center;"); m_pColumnTable->setCellWidget(row, col, comboBox); } void nmWxDFNLoadFromFile::onCellChanged(int row, int col) { // 仅处理Type行(1)的变更 if (row != 1) return; // 获取新的Type值 QTableWidgetItem* typeItem = m_pColumnTable->item(1, col); if (!typeItem) return; QString newType = typeItem->text(); // 获取对应的默认Unit QString defaultUnit = m_typeToDefaultUnit.value(newType, ""); // 更新Unit行 QTableWidgetItem* unitItem = m_pColumnTable->item(2, col); if (unitItem) { unitItem->setText(defaultUnit); } else { unitItem = new QTableWidgetItem(defaultUnit); unitItem->setTextAlignment(Qt::AlignCenter); m_pColumnTable->setItem(2, col, unitItem); } } void nmWxDFNLoadFromFile::closeOpenComboBox() { // 遍历所有单元格,关闭已打开的下拉框 for (int r = 0; r < m_pColumnTable->rowCount(); ++r) { for (int c = 0; c < m_pColumnTable->columnCount(); ++c) { QWidget* widget = m_pColumnTable->cellWidget(r, c); if (widget && qobject_cast(widget)) { QComboBox* comboBox = static_cast(widget); QString selectedText = comboBox->currentText(); // 保存值到表格项 QTableWidgetItem* item = m_pColumnTable->item(r, c); if (item) { item->setText(selectedText); } else { item = new QTableWidgetItem(selectedText); item->setTextAlignment(Qt::AlignCenter); m_pColumnTable->setItem(r, c, item); } // 移除下拉框 m_pColumnTable->setCellWidget(r, c, nullptr); delete comboBox; } } } } void nmWxDFNLoadFromFile::updateSeparators() { // 检查是否有文件加载 QString filePath = m_pFilePathEdit->text(); if (filePath.isEmpty()) { return; } // 重新加载文件以应用新的分隔符 //loadTextFile(filePath); // 如果是文本文件,重新加载以应用新的分隔符 if (filePath.endsWith(".txt", Qt::CaseInsensitive)) { // 读取文件内容 QStringList lines = readFileContent(filePath); if (lines.isEmpty()) { return; } // 解析内容 QRegExp separatorRegex = buildSeparatorRegex(); QList parsedData; for (int i = 0; i < lines.size(); ++i) { parsedData << lines[i].split(separatorRegex, QString::SkipEmptyParts); } // 处理数据 clearDataRows(); setupTableColumns(parsedData.isEmpty() ? 0 : parsedData[0].size()); populateDataRows(parsedData); } } void nmWxDFNLoadFromFile::onOkClicked() { QVector vecDatas; // 检查是否有足够的数据行(至少4行:表头+1行数据) if (m_pColumnTable->rowCount() < 4) { QMessageBox::warning(this, tr("Error"), tr("No data rows found")); return; } // 检查列数是否足够 if (m_pColumnTable->columnCount() == 0) { QMessageBox::warning(this, tr("Error"), tr("No columns defined")); return; } // 首先收集每列的类型和单位信息 QVector columnTypes; for (int col = 0; col < m_pColumnTable->columnCount(); ++col) { QTableWidgetItem* typeItem = m_pColumnTable->item(1, col); QString type = typeItem ? typeItem->text() : "UnDefined"; columnTypes.append(type); } // 检查是否设置了必需的列(X1, Y1, X2, Y2) bool hasX1 = columnTypes.contains("X1"); bool hasY1 = columnTypes.contains("Y1"); bool hasX2 = columnTypes.contains("X2"); bool hasY2 = columnTypes.contains("Y2"); if (!hasX1 || !hasY1 || !hasX2 || !hasY2) { QMessageBox::warning(this, tr("Error"), tr("Required columns (X1, Y1, X2, Y2) are not all defined")); return; } // 从第4行开始读取数据(前3行是表头) for (int row = 3; row < m_pColumnTable->rowCount(); ++row) { DFNData dataRow; // 检查是否定义了Fc、Wf、o列 bool hasFc = columnTypes.contains("Fc"); bool hasWf = columnTypes.contains("Wf"); bool hasO = columnTypes.contains("o"); // 定义默认值 const double defaultFc = 0.1; const double defaultWf = 0.00328084; const double defaultO = 10.0; // 在循环内部处理 for (int col = 0; col < m_pColumnTable->columnCount(); ++col) { QTableWidgetItem* item = m_pColumnTable->item(row, col); QString value = item ? item->text() : ""; QString type = columnTypes[col]; bool ok; double numValue = value.toDouble(&ok); if (type == "X1") { if (ok) dataRow.x1 = numValue; } else if (type == "Y1") { if (ok) dataRow.y1 = numValue; } else if (type == "X2") { if (ok) dataRow.x2 = numValue; } else if (type == "Y2") { if (ok) dataRow.y2 = numValue; } else if (type == "Fc") { if (ok) dataRow.fc = numValue; } else if (type == "Wf") { if (ok) dataRow.wf = numValue; } else if (type == "o") { if (ok) dataRow.o = numValue; } } // 如果用户未分配该列,则填充默认值 if (!hasFc) dataRow.fc = defaultFc; if (!hasWf) dataRow.wf = defaultWf; if (!hasO) dataRow.o = defaultO; vecDatas.append(dataRow); } // 清空原来的DFN图元数据 if (!nmDataAnalyzeManager::getCurrentInstance()->getDFNFractureDataList().isEmpty()) { nmGuiPlot* pCurPlot = nmDataAnalyzeManager::getCurrentInstance()->getPlot(); pCurPlot->deleteAllDFNPlots(); } // 遍历vecDatas,将数据存入数据中心 foreach (const DFNData &data, vecDatas) { nmDataFracture* pFractrue = nmDataAnalyzeManager::getCurrentInstance()->createFracture(); // 裂缝名称 pFractrue->setFractureName("DFN"); // 裂缝位置信息 QPointF pt1(data.x1,data.y1); QPointF pt2(data.x2,data.y2); QVector vecPts; vecPts.append(pt1); vecPts.append(pt2); pFractrue->setFracturePoints(vecPts); // 裂缝流动类型,默认为无限导流 nmDataAttribute tempAttr = pFractrue->getFractureFlowModel(); tempAttr.setValue(tr("Finite Conductivity")); pFractrue->setFractureFlowModel(tempAttr); // 裂缝导流能力 tempAttr = pFractrue->getFractureDfc(); tempAttr.setValue(data.fc); pFractrue->setFractureDfc(tempAttr); // TODO:裂缝宽度 // TODO:裂缝孔隙度 // 新增:裂缝类型,区分普通裂缝和DFN生成的裂缝 tempAttr = pFractrue->getFractureType(); tempAttr.setValue(tr("DFN")); pFractrue->setFractureType(tempAttr); nmGuiPlot* pCurPlot = nmDataAnalyzeManager::getCurrentInstance()->getPlot(); if (pCurPlot != nullptr) { // 添加一条裂缝 QString sName = pFractrue->getFractureName(); QVector vecFracurePts =pFractrue->getFracturePoints(); // 转换坐标 QVector vecConvertPoints = pCurPlot->m_pPlot->getPosForValue(vecFracurePts); nmObjLineCrack* pFractrePlot = (nmObjLineCrack*)pCurPlot->appendOneObj(NMOT_Line_Fracture, sName,vecConvertPoints); if(pFractrePlot == nullptr) { continue; } // 绑定边界数据到图元对象上 pFractrePlot->setFractureData(pFractrue); pFractrePlot->setPen(QPen(QBrush(QColor("#00bfff")), 0.4f, Qt::SolidLine)); pFractrePlot->setLockForDFN(); } } // 如果一切正常,接受对话框 this->accept(); } void nmWxDFNLoadFromFile::onCancelClicked() { this->reject(); } // 清除数据行(保留表头行) void nmWxDFNLoadFromFile::clearDataRows() { while (m_pColumnTable->rowCount() > 3) { m_pColumnTable->removeRow(3); } } // 构建分隔符正则表达式 QRegExp nmWxDFNLoadFromFile::buildSeparatorRegex() const { QStringList separators; if (m_pSpaceCheck->isChecked()) { separators << " "; } if (m_pTabCheck->isChecked()) { separators << "\\t"; } if (!m_pOtherSeparatorEdit->text().isEmpty()) { separators << QRegExp::escape(m_pOtherSeparatorEdit->text()); } return QRegExp(QString("[%1]+").arg(separators.join(""))); } // 设置表格列 void nmWxDFNLoadFromFile::setupTableColumns(int columnCount) { m_pColumnTable->setColumnCount(columnCount); for (int col = 0; col < columnCount; ++col) { // Column行 QTableWidgetItem* colItem = new QTableWidgetItem(QString("Column %1").arg(col + 1)); colItem->setFlags((colItem->flags() & ~Qt::ItemIsEditable) | Qt::ItemIsSelectable | Qt::ItemIsEnabled); m_pColumnTable->setItem(0, col, colItem); // Type行 QString defaultType = (col < m_allTypeOptions.size()) ? m_allTypeOptions[col] : "UnDefined"; m_pColumnTable->setItem(1, col, new QTableWidgetItem(defaultType)); // Unit行 QString defaultUnit = m_typeToDefaultUnit.value(defaultType, ""); m_pColumnTable->setItem(2, col, new QTableWidgetItem(defaultUnit)); } } // 填充数据行 void nmWxDFNLoadFromFile::populateDataRows(const QList& dataLines) { for (int row = 0; row < dataLines.size(); ++row) { const QStringList& values = dataLines[row]; m_pColumnTable->insertRow(row + 3); for (int col = 0; col < values.size(); ++col) { QTableWidgetItem* item = new QTableWidgetItem(values[col]); item->setFlags((item->flags() & ~Qt::ItemIsEditable) | Qt::ItemIsSelectable | Qt::ItemIsEnabled); m_pColumnTable->setItem(row + 3, col, item); } } } // 读取文本文件内容 QStringList nmWxDFNLoadFromFile::readFileContent(const QString& filePath) { QStringList lines; QFile file(filePath); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { QMessageBox::warning(this, tr("Error"), tr("Could not open file")); return lines; } QTextStream in(&file); while (!in.atEnd()) { QString line = in.readLine().trimmed(); if (!line.isEmpty()) { lines << line; } } file.close(); return lines; } // 解析Excel数据 QList nmWxDFNLoadFromFile::parseExcelData(QString filePath) { QList result; ExcelUtils excelUtils; QString log; VVecVariant data; if (!excelUtils.loadExcel(data, NULL, filePath, log)) { QMessageBox::warning(this, tr("Import Error"), tr("Failed to import Excel : \n") + log); return result; } // 转换VVecVariant到QList for (int i = 0; i < data.size(); ++i) { QStringList row; for (int j = 0; j < data[i].size(); ++j) { row << data[i][j].toString(); } result << row; } return result; }