#include "nmWxResultParameters.h" //#include "nmAttributeDelegate.h" #include #include "nmDataAnalyzeManager.h" #include "nmDataWellBase.h" #include "nmDataVerticalWell.h" #include "nmDataMixedResults.h" #include "nmDataPvtParaForPebi.h" #include "nmTranslationManager.h" CustomTreeWidget::CustomTreeWidget(QWidget *parent) : QTreeWidget(parent) { m_isResizing = false; m_resizeColumn = 0; m_resizeStartX = 0; m_resizeStartWidth = 0; } void CustomTreeWidget::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { // 检查是否在列分割线附近 int x = event->pos().x(); int colWidth = columnWidth(0); int handleWidth = 5; // 拖动热区宽度 if (abs(x - colWidth) < handleWidth) { m_isResizing = true; m_resizeColumn = 0; m_resizeStartX = x; m_resizeStartWidth = colWidth; setCursor(Qt::SplitHCursor); return; } } // 原有item点击处理 QTreeWidget::mousePressEvent(event); } void CustomTreeWidget::mouseMoveEvent(QMouseEvent *event) { if (m_isResizing) { int newWidth = m_resizeStartWidth + (event->pos().x() - m_resizeStartX); setColumnWidth(m_resizeColumn, qMax(50, newWidth)); // 最小宽度50px viewport()->update(); return; } else { // 检查是否在分割线附近 int x = event->pos().x(); int colWidth = columnWidth(0); int handleWidth = 5; if (abs(x - colWidth) < handleWidth) { setCursor(Qt::SplitHCursor); } else { unsetCursor(); } } QTreeWidget::mouseMoveEvent(event); } void CustomTreeWidget::mouseReleaseEvent(QMouseEvent *event) { if (m_isResizing) { m_isResizing = false; unsetCursor(); return; } QTreeWidget::mouseReleaseEvent(event); } void CustomTreeWidget::paintEvent(QPaintEvent *event) { QTreeWidget::paintEvent(event); // 绘制列分割线 /*QPainter painter(viewport()); painter.setPen(QPen(QColor("#c8c8c8"), 1)); int colWidth = columnWidth(0); int h = height(); int p = this->height(); painter.drawLine(colWidth, 0, colWidth, height());*/ } #include #include CustomTreeDelegate::CustomTreeDelegate(QObject *parent) : QStyledItemDelegate(parent), m_iconSize(17, 17) { // 方法2:绝对路径(推荐) QString appDir = QCoreApplication::applicationDirPath(); appDir = appDir.section('/', 0, -2); // 获取上一级目录 QString expandDir = appDir + "/Res/Icon/Expand.png"; QString collapseDir = appDir + "/Res/Icon/Collapse.png"; m_expandIcon.load(expandDir); m_collapseIcon.load(collapseDir); } void CustomTreeDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { if (!painter || !index.isValid()) return; painter->save(); QStyleOptionViewItem opt = option; initStyleOption(&opt, index); // 1. 绘制背景 drawBackground(painter, opt, index); // 2. 处理字体样式 QFont baseFont = opt.font; bool isSelected = opt.state & QStyle::State_Selected; if (index.column() == 0) { // 第一列:选中时加粗 if (isSelected) { baseFont.setBold(true); //baseFont.setPointSize(baseFont.pointSize() + 1); } drawFirstColumn(painter, opt, index, baseFont); } else if (index.column() == 1) { // 第二列:数值加粗(选中时),单位斜体 drawSecondColumn(painter, opt, index, baseFont, isSelected); } else { // 其他列 painter->setFont(baseFont); painter->drawText(opt.rect, Qt::AlignLeft | Qt::AlignVCenter, index.data().toString()); } // 2. 绘制网格线(包括可拉伸的列间竖线) painter->setPen(QColor("#c8c8c8")); drawGridLines(painter, opt, index); painter->restore(); } // 绘制背景 void CustomTreeDelegate::drawBackground(QPainter* painter, QStyleOptionViewItem& opt, const QModelIndex& index) const { if (opt.state & QStyle::State_Selected) { painter->fillRect(opt.rect, opt.palette.highlight()); } else if (!index.parent().isValid()) { painter->fillRect(opt.rect, QColor("#faf5f0")); // 根节点背景 } else { painter->fillRect(opt.rect, opt.palette.base()); } } // 绘制第一列(带图标) void CustomTreeDelegate::drawFirstColumn(QPainter* painter, QStyleOptionViewItem& opt, const QModelIndex& index, const QFont& font) const { QTreeWidget* tree = qobject_cast(parent()); if (!tree) return; QRect itemRect = opt.rect; QColor textColor; // 字体颜色 QFont modifiedFont = font; // 复制原始字体 // 绘制可展开图标 if (index.model()->hasChildren(index)) { QRect iconRect( opt.rect.left() + 3, opt.rect.top() + (opt.rect.height() - m_iconSize.height()) / 2, // 垂直居中 m_iconSize.width(), m_iconSize.height() ); const QPixmap& icon = tree->isExpanded(index) ? m_expandIcon : m_collapseIcon; painter->drawPixmap(iconRect, icon); //itemRect.adjust(m_iconSize.width(), 0, 0, 0); // 调整文本位置 itemRect.adjust(20 + 2, 0, 0, 0); // 调整文本位置 textColor = QColor("#606060"); modifiedFont.setBold(true); // 有子节点:加粗 } else { textColor = opt.palette.text().color(); itemRect.adjust(2, 0, 0, 0); // 调整文本位置,向左2px } // 绘制文本 painter->setFont(modifiedFont); painter->setPen(textColor); painter->drawText(itemRect, Qt::AlignLeft | Qt::AlignVCenter, index.data().toString()); } // 绘制第二列(数值+单位) void CustomTreeDelegate::drawSecondColumn(QPainter* painter, const QStyleOptionViewItem& opt, const QModelIndex& index, const QFont& baseFont, bool isSelected) const { QString text = index.data(Qt::DisplayRole).toString(); QStringList parts = text.split(" "); if (parts.size() >= 2) { // 数值部分(选中时加粗) QFont valueFont = baseFont; if (isSelected) valueFont.setBold(true); painter->setFont(valueFont); QRect valueRect = opt.rect.adjusted(2, 0, -opt.rect.width()/2, 0); painter->drawText(valueRect, Qt::AlignLeft | Qt::AlignVCenter, parts[0]); // 单位部分(选中时为斜体) QFont unitFont = baseFont; if (isSelected) unitFont.setItalic(true); painter->setFont(unitFont); QRect unitRect = opt.rect.adjusted(opt.rect.width()/2, 0, -2, 0); painter->drawText(unitRect, Qt::AlignRight | Qt::AlignVCenter, parts[1]); } else { // 只有值 QFont valueFont = baseFont; if (isSelected) valueFont.setBold(true); QRect valueRect = opt.rect.adjusted(2, 0, -opt.rect.width()/2, 0); painter->setFont(valueFont); painter->drawText(valueRect, Qt::AlignLeft | Qt::AlignVCenter, text); } } // 绘制网格线 void CustomTreeDelegate::drawGridLines(QPainter* painter, const QStyleOptionViewItem& opt, const QModelIndex& index) const { QTreeWidget* tree = qobject_cast(parent()); if (!tree) return; // 判断条件 bool hasChildren = index.model()->hasChildren(index); bool isLast = isLastSibling(index); bool bIsExpanded = tree->isExpanded(index) ? true : false; // 底部横线 // 父节点并且处于展开状态 if (hasChildren && bIsExpanded) { painter->drawLine(opt.rect.left() + 20, opt.rect.bottom(), opt.rect.right(), opt.rect.bottom()); } else if (isLast){ // 最后一个子节点 painter->drawLine(opt.rect.left() - 20, opt.rect.bottom(), opt.rect.right(), opt.rect.bottom()); } else { painter->drawLine(opt.rect.bottomLeft(), opt.rect.bottomRight()); } // 第一列右侧竖线(可拉伸) if(index.column() == 0) { painter->drawLine(opt.rect.topRight(), opt.rect.bottomRight()); } } bool CustomTreeDelegate::isLastSibling(const QModelIndex& index) const { if (!index.isValid() || !index.parent().isValid()) { return false; } const QAbstractItemModel* model = index.model(); int rowCount = model->rowCount(index.parent()); return (index.row() == rowCount - 1); } bool CustomTreeDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) { if (event->type() == QEvent::MouseButtonPress) { QMouseEvent* me = static_cast(event); QTreeWidget* tree = qobject_cast(parent()); // 检测是否点击了图标区域 QRect iconRect(option.rect.left(), option.rect.top() + (option.rect.height() - m_iconSize.height())/2, m_iconSize.width(), m_iconSize.height()); if (iconRect.contains(me->pos())) { tree->setExpanded(index, !tree->isExpanded(index)); // 切换展开状态 return true; // 事件已处理 } } return QStyledItemDelegate::editorEvent(event, model, option, index); } #include "nmDataReservoir.h" nmWxResultParameters::nmWxResultParameters(QWidget *parent) : QWidget(parent) { m_pLayout = nullptr; m_pTreeWidget = nullptr; this->initUI(); // 加载结果参数 this->loadResultDatas(); m_pTreeWidget->expandAll(); //this->resize(700, 400); } nmWxResultParameters::~nmWxResultParameters() { if (m_pTreeWidget != nullptr) { delete m_pTreeWidget; m_pTreeWidget = nullptr; } } void nmWxResultParameters::initUI() { this->initLayout(); this->initComponents(); } void nmWxResultParameters::initLayout() { m_pLayout = new QVBoxLayout(this); m_pLayout->setContentsMargins(0, 0, 0, 0); m_pLayout->setSpacing(0); } void nmWxResultParameters::initComponents() { if (m_pTreeWidget != nullptr) { delete m_pTreeWidget; m_pTreeWidget = nullptr; } m_pTreeWidget = new CustomTreeWidget; m_pTreeWidget->setColumnCount(2); m_pTreeWidget->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::SelectedClicked); CustomTreeDelegate *delegate = new CustomTreeDelegate(m_pTreeWidget); m_pTreeWidget->setItemDelegate(delegate); m_pTreeWidget->setIndentation(20); // 缩进20px // 隐藏表头 m_pTreeWidget->setHeaderHidden(true); // 使用以下样式表设置 m_pTreeWidget->setStyleSheet( "QTreeWidget {" //" border: 1px solid #c8c8c8;" " border:none;" " font-family: 'Microsoft YaHei';" " font-size: 9pt;" " background: white;" "}" "QTreeWidget::item {" " height: 25px;" " margin: 0px;" "}" "QTreeWidget::branch{" " width: 19px;" " height: 25px;" " border-right: 1px solid #c8c8c8;" // 垂直右边框 " background: #faf5f0;" "}" ); m_pTreeWidget->setColumnWidth(0, m_pTreeWidget->width()/2); m_pTreeWidget->setColumnWidth(1, m_pTreeWidget->width()/2); m_pTreeWidget->header()->setStretchLastSection(true); // 最后一项充满 m_pTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection); // 是否可以选择多个项目 m_pTreeWidget->setSelectionBehavior(QAbstractItemView::SelectRows);// 设置选择行或者列 m_pTreeWidget->setRootIsDecorated(false); // 设置最顶层的节点是否显示前面小箭头 m_pTreeWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); // 设置是否开启滚动条 m_pLayout->addWidget(m_pTreeWidget); } void nmWxResultParameters::loadResultDatas() { nmDataAnalyzeManager* pDataManager = nmDataAnalyzeManager::getCurrentInstance(); // 获取混合参数 nmDataMixedResults* pMixedResults = pDataManager->getMixedResults(); // 获取井参数 QVector vecResultWells = pDataManager->getWellDataList(); // 获取储层参数 nmDataReservoir* pResultReservoir = pDataManager->getReservoirData(); // 获取Pebi网格的PVT输入参数 nmDataPvtParaForPebi* pPvtPara = pDataManager->getPebiPvtPara(); // 添加结果参数到树上 appendMixedResultsToTree(pMixedResults,vecResultWells[0],pResultReservoir,pPvtPara); } void nmWxResultParameters::appendMixedResultsToTree(nmDataMixedResults* mixedResults,nmDataWellBase* well,nmDataReservoir* reservoir,nmDataPvtParaForPebi* pvtPara) { // Warnings---提示 QTreeWidgetItem* pWarningsItem = new QTreeWidgetItem(m_pTreeWidget); pWarningsItem->setText(0, tr("Warnings")); pWarningsItem->setFlags(pWarningsItem->flags() & ~Qt::ItemIsEditable); // 设置为不可编辑 addAttributeToTree(pWarningsItem,mixedResults->getCriticalParameters()); // Analysis summary---分析总结 QTreeWidgetItem* pAnalysisSummaryItem = new QTreeWidgetItem(m_pTreeWidget); pAnalysisSummaryItem->setText(0, tr("Analysis summary")); pAnalysisSummaryItem->setFlags(pAnalysisSummaryItem->flags() & ~Qt::ItemIsEditable); // 设置为不可编辑 addAttributeToTree(pAnalysisSummaryItem,mixedResults->getAnalysisName()); // 获取当前井 nmDataAttribute curWellAttr = mixedResults->getReferenceWell(); curWellAttr.setValue(well->getWellName()); mixedResults->setReferenceWell(curWellAttr); addAttributeToTree(pAnalysisSummaryItem,mixedResults->getReferenceWell()); addAttributeToTree(pAnalysisSummaryItem,mixedResults->getPVTReferencePhase()); addAttributeToTree(pAnalysisSummaryItem,mixedResults->getPVTPhases()); addAttributeToTree(pAnalysisSummaryItem,mixedResults->getActiveProduction()); addAttributeToTree(pAnalysisSummaryItem,mixedResults->getActivePressureGauge()); addAttributeToTree(pAnalysisSummaryItem,mixedResults->getAnalysisType()); addAttributeToTree(pAnalysisSummaryItem,mixedResults->getActiveModel()); // Main Results---主要结果 QTreeWidgetItem* pMainResultsItem = new QTreeWidgetItem(m_pTreeWidget); pMainResultsItem->setText(0, tr("Main Results")); pMainResultsItem->setFlags(pMainResultsItem->flags() & ~Qt::ItemIsEditable); // 设置为不可编辑 addAttributeToTree(pMainResultsItem,mixedResults->getSource()); addAttributeToTree(pMainResultsItem,reservoir->getTransmissibility()); addAttributeToTree(pMainResultsItem,reservoir->getPermeability()); addAttributeToTree(pMainResultsItem,mixedResults->getMobility()); //addAttributeToTree(pMainResultsItem,well->getSkin()); // 获取第一段射孔的表皮系数 addAttributeToTree(pMainResultsItem, well->getPerforation(0)->getSkin()); addAttributeToTree(pMainResultsItem,reservoir->getInitialPressure()); addAttributeToTree(pMainResultsItem,well->getWellboreStorage()); addAttributeToTree(pMainResultsItem,mixedResults->getPbar()); addAttributeToTree(pMainResultsItem,mixedResults->getProductivityIndex()); addAttributeToTree(pMainResultsItem,mixedResults->getPoreVolume()); // Diagnostic---诊断分析 QTreeWidgetItem* pDiagnosticItem = new QTreeWidgetItem(m_pTreeWidget); pDiagnosticItem->setText(0, tr("Diagnostic")); pDiagnosticItem->setFlags(pDiagnosticItem->flags() & ~Qt::ItemIsEditable); // 设置为不可编辑 addAttributeToTree(pMainResultsItem,well->getWellboreStorage()); addAttributeToTree(pDiagnosticItem,mixedResults->getDiagnosticWell()); addAttributeToTree(pMainResultsItem,reservoir->getReservoirType()); addAttributeToTree(pDiagnosticItem,mixedResults->getBoundary()); addAttributeToTree(pDiagnosticItem,mixedResults->getReferenceRate()); addAttributeToTree(pDiagnosticItem,mixedResults->getExtractionStartTime()); addAttributeToTree(pDiagnosticItem,mixedResults->getPAtDt0()); addAttributeToTree(pMainResultsItem,mixedResults->getProductivityIndex()); addAttributeToTree(pDiagnosticItem,mixedResults->getTimeMatch()); addAttributeToTree(pDiagnosticItem,mixedResults->getPressureMatch()); addAttributeToTree(pMainResultsItem,well->getWellboreStorage()); addAttributeToTree(pMainResultsItem,reservoir->getTransmissibility()); addAttributeToTree(pMainResultsItem,reservoir->getPermeability()); addAttributeToTree(pMainResultsItem,mixedResults->getMobility()); addAttributeToTree(pDiagnosticItem,mixedResults->getKhMu()); //addAttributeToTree(pMainResultsItem,well->getSkin()); // 获取第一段射孔的表皮系数 addAttributeToTree(pMainResultsItem, well->getPerforation(0)->getSkin()); addAttributeToTree(pDiagnosticItem,mixedResults->getDeltaPSkin()); // Model description---模型表征 QTreeWidgetItem* pModelDescriptionItem = new QTreeWidgetItem(m_pTreeWidget); pModelDescriptionItem->setText(0, tr("Model description")); pModelDescriptionItem->setFlags(pModelDescriptionItem->flags() & ~Qt::ItemIsEditable); // 设置为不可编辑 addAttributeToTree(pModelDescriptionItem,mixedResults->getActiveModel()); addAttributeToTree(pModelDescriptionItem,well->getWellboreModel()); if (auto vfWell = dynamic_cast(well)){ // 压裂直井 addAttributeToTree(pModelDescriptionItem, nmDataAttribute(tr("Well Type"),tr("Vertical Fractured"),"")); } else if (auto hfWell = dynamic_cast(well)) { // 多级压裂水平井 addAttributeToTree(pModelDescriptionItem, nmDataAttribute(tr("Well Type"),tr("Horizontal Fractured"),"")); } else if (auto vWell = dynamic_cast(well)) { // 直井 addAttributeToTree(pModelDescriptionItem, nmDataAttribute(tr("Well Type"),tr("Vertical"),"")); } addAttributeToTree(pModelDescriptionItem,reservoir->getReservoirType()); addAttributeToTree(pModelDescriptionItem,mixedResults->getBoundary()); addAttributeToTree(pModelDescriptionItem,mixedResults->getOtherWellsIncluded()); addAttributeToTree(pModelDescriptionItem,mixedResults->getRateDependentSkin()); addAttributeToTree(pModelDescriptionItem,mixedResults->getTimeDependentSkin()); // Model - 井 appendWellToTree(well); // Model - Reservoir 油藏参数 appendReservoirToTree(reservoir); // Model - Contour & faults---模型-边界和断层 QTreeWidgetItem* pModelCFItem = new QTreeWidgetItem(m_pTreeWidget); pModelCFItem->setText(0, tr("Model - Contour & faults")); pModelCFItem->setFlags(pModelCFItem->flags() & ~Qt::ItemIsEditable); // 设置为不可编辑 addAttributeToTree(pModelCFItem,mixedResults->getTopBoundary()); addAttributeToTree(pModelCFItem,mixedResults->getBottomBoundary()); // Model - Results - Field---模型-结果-场 QTreeWidgetItem* pModelRFItem = new QTreeWidgetItem(m_pTreeWidget); pModelRFItem->setText(0, tr("Model - Results - Field")); pModelRFItem->setFlags(pModelRFItem->flags() & ~Qt::ItemIsEditable); // 设置为不可编辑 addAttributeToTree(pModelRFItem,mixedResults->getSTOIIP()); addAttributeToTree(pModelRFItem,mixedResults->getSTOIIPFree()); addAttributeToTree(pModelRFItem,mixedResults->getQoTmax()); addAttributeToTree(pModelRFItem,mixedResults->getTmax()); addAttributeToTree(pModelRFItem,mixedResults->getArea()); addAttributeToTree(pModelRFItem,mixedResults->getBulkVolume()); addAttributeToTree(pMainResultsItem,mixedResults->getPoreVolume()); // Test parameters---测试参数 QTreeWidgetItem* pTestParametersItem = new QTreeWidgetItem(m_pTreeWidget); pTestParametersItem->setText(0, tr("Model - Results - Field")); pTestParametersItem->setFlags(pTestParametersItem->flags() & ~Qt::ItemIsEditable); // 设置为不可编辑 addAttributeToTree(pTestParametersItem,well->getRadius()); addAttributeToTree(pTestParametersItem,reservoir->getThickness()); addAttributeToTree(pTestParametersItem, reservoir->getCf()); // 岩石压缩系数 //if (pvtPara != nullptr) { // 岩石压缩系数 //addAttributeToTree(pTestParametersItem,nmDataAttribute(tr("Rock compressibility"),pvtPara->getCfCfinitial()[0],tr("psi-1"))); //addAttributeToTree(rootItem, reservoir->getCf()); //} addAttributeToTree(pTestParametersItem,reservoir->getPorosity()); //addAttributeToTree(pTestParametersItem,nmDataAttribute(tr("Rock compressibility"),pvtPara->getCfCfinitial()[0],tr("psi-1"))); addAttributeToTree(pTestParametersItem,nmDataAttribute(tr("Top reservoir depth"),6000.0,tr("m"))); // PVT---PVT QTreeWidgetItem* pPVTItem = new QTreeWidgetItem(m_pTreeWidget); pPVTItem->setText(0, tr("Model - Results - Field")); pPVTItem->setFlags(pPVTItem->flags() & ~Qt::ItemIsEditable); // 设置为不可编辑 addAttributeToTree(pPVTItem,mixedResults->getPVTReferencePhase()); // 获取PVT相关参数 // Formation volume factor // Viscosity // Total compressibility // Oil saturation // Water compressibility (cw) // Oil compressibility (co) // Gas compressibility (cg) if (pvtPara != nullptr) { // 体积系数 addAttributeToTree(pPVTItem,nmDataAttribute(tr("Formation volume factor"),pvtPara->getBo()[0],tr("B/STB"))); // 粘度 addAttributeToTree(pPVTItem,nmDataAttribute(tr("Viscosity"),pvtPara->getBo()[0],tr("cp"))); // 综合压缩系数 addAttributeToTree(pPVTItem,reservoir->getCt()); // 含油饱和度 addAttributeToTree(pPVTItem,nmDataAttribute(tr("Oil saturation"),pvtPara->getSo()[0],"")); // 水压缩系数 addAttributeToTree(pPVTItem,nmDataAttribute(tr("Water compressibility (cw)"),pvtPara->getCw()[0],tr("psi-1"))); // 油压缩系数 addAttributeToTree(pPVTItem,nmDataAttribute(tr("Oil compressibility (co)"),pvtPara->getCo()[0],tr("psi-1"))); // 气压缩系数 addAttributeToTree(pPVTItem,nmDataAttribute(tr("Gas compressibility (cg)"),pvtPara->getCg()[0],tr("psi-1"))); } // Statistics---统计 QTreeWidgetItem* pStatisticsItem = new QTreeWidgetItem(m_pTreeWidget); pStatisticsItem->setText(0, tr("Statistics")); pStatisticsItem->setFlags(pStatisticsItem->flags() & ~Qt::ItemIsEditable); // 设置为不可编辑 addAttributeToTree(pStatisticsItem,mixedResults->getGoodnessOfFit()); } void nmWxResultParameters::appendWellToTree(nmDataWellBase* well) { QTreeWidgetItem* wellItem = new QTreeWidgetItem(m_pTreeWidget); wellItem->setText(0, tr("Model - ") + well->getWellName()); wellItem->setFlags(wellItem->flags() & ~Qt::ItemIsEditable); // 设置为不可编辑 // 添加井的属性作为子节点 addAttributeToTree(wellItem, well->getDrillFloorElevation()); addAttributeToTree(wellItem, well->getRadius()); addAttributeToTree(wellItem, well->getZw()); if (auto vfWell = dynamic_cast(well)){ // 压裂直井 addAttributeToTree(wellItem, vfWell->getPerforationLength()); } else if (auto hfWell = dynamic_cast(well)) { // 多级压裂水平井 // k.Xmf² k.Xmf² // A.√k A.√k addAttributeToTree(wellItem, nmDataAttribute(tr("kXmf"),tr("kXmf"),"")); addAttributeToTree(wellItem, nmDataAttribute(tr("Ak"),tr("Ak"),"")); } else if (auto vWell = dynamic_cast(well)) { // 直井 addAttributeToTree(wellItem, vWell->getPerforationLength()); } addAttributeToTree(wellItem, well->getWellLength()); // TODO:遍历整个射孔段 //addAttributeToTree(wellItem, well->getMyName()); //addAttributeToTree(wellItem, well->getMdStart()); //addAttributeToTree(wellItem, well->getMdEnd()); //addAttributeToTree(wellItem, well->getSkin()); addAttributeToTree(wellItem, well->getWellboreModel()); addAttributeToTree(wellItem, well->getWellboreStorage()); addAttributeToTree(wellItem, well->getBottomholeMD()); } void nmWxResultParameters::appendReservoirToTree(nmDataReservoir* reservoir) { // 创建根节点 QTreeWidgetItem* rootItem = new QTreeWidgetItem(m_pTreeWidget); rootItem->setText(0, tr("Model - Reservoir")); rootItem->setFlags(rootItem->flags() & ~Qt::ItemIsEditable); // 不可编辑状态 // 添加成员变量作为子节点 addAttributeToTree(rootItem, reservoir->getInitialPressure()); addAttributeToTree(rootItem, reservoir->getReservoirType()); addAttributeToTree(rootItem,reservoir->getTransmissibility()); addAttributeToTree(rootItem,reservoir->getPermeability()); addAttributeToTree(rootItem, reservoir->getThickness()); addAttributeToTree(rootItem, reservoir->getMiuo()); addAttributeToTree(rootItem, reservoir->getBo()); addAttributeToTree(rootItem, reservoir->getPorosity()); addAttributeToTree(rootItem, reservoir->getCt()); addAttributeToTree(rootItem, reservoir->getKxKy()); addAttributeToTree(rootItem, reservoir->getCf()); } // 辅助函数:添加属性到树 void nmWxResultParameters::addAttributeToTree(QTreeWidgetItem* parent,const nmDataAttribute& attr) { QTreeWidgetItem* item = new QTreeWidgetItem(parent); item->setText(0, nmTranslationManager::mapToChinese(attr.getName())); // 获取属性的值/单位 QVariant value = attr.getValue(); QString unit = attr.getUnit(); // 第二列显示值和单位 item->setText(1, nmTranslationManager::mapToChinese(formatAttributeValue(value, unit))); } QString nmWxResultParameters::formatAttributeValue(const QVariant& value, const QString& unit) { QString valueText; // 1. 解析 QVariant 值 switch (value.type()) { case QVariant::Double: //valueText = QString::number(value.toDouble(), 'f', 4); // 保留4位小数 valueText = QString::number(value.toDouble()); break; case QVariant::Int: case QVariant::UInt: valueText = QString::number(value.toInt()); break; case QVariant::String: valueText = value.toString(); break; default: valueText = "N/A"; // 未知类型 break; } // 2. 处理单位(非空时追加) if (!unit.isEmpty()) { valueText += " " + unit; } return valueText; }