|
|
|
|
|
#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;
|
|
|
|
|
|
}
|