You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nmWTAI-Platform/Src/nmNum/nmSubWxs/nmWxResultParameters.cpp

681 lines
26 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "nmWxResultParameters.h"
//#include "nmAttributeDelegate.h"
#include <QHeaderView>
#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 <QPainter>
#include <QAbstractItemModel>
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<QTreeWidget*>(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<QTreeWidget*>(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<QMouseEvent*>(event);
QTreeWidget* tree = qobject_cast<QTreeWidget*>(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<nmDataWellBase*> 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<nmDataVerticalFracturedWell*>(well)){
// 压裂直井
addAttributeToTree(pModelDescriptionItem, nmDataAttribute(tr("Well Type"),tr("Vertical Fractured"),""));
} else if (auto hfWell = dynamic_cast<nmDataHorizontalFracturedWell*>(well)) {
// 多级压裂水平井
addAttributeToTree(pModelDescriptionItem, nmDataAttribute(tr("Well Type"),tr("Horizontal Fractured"),""));
} else if (auto vWell = dynamic_cast<nmDataVerticalWell*>(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<nmDataVerticalFracturedWell*>(well)){
// 压裂直井
addAttributeToTree(wellItem, vfWell->getPerforationLength());
} else if (auto hfWell = dynamic_cast<nmDataHorizontalFracturedWell*>(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<nmDataVerticalWell*>(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;
}