#include "nmWxGeometryLayerDlg.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "nmGUIComponentBase.h" #include "nmDataReservoir.h" #include "nmDataAnalyzeManager.h" Q_DECLARE_METATYPE(double *) nmWxGeometryLayerDlg::nmWxGeometryLayerDlg(){ m_pReservoir = nmDataAnalyzeManager::getCurrentInstance()->getReservoirData(); this->initUI(); this->initLayers(); // 确保在UI初始化后立即初始化层数据 this->updateLayers(); // 更新UI以显示初始数据 this->setWindowTitle(tr("Layer Setting")); this->resize(500,300); } void nmWxGeometryLayerDlg::initUI() { mainLayout = new QVBoxLayout; this->setLayout(mainLayout); QGridLayout* gridLayout = new QGridLayout(); mainLayout->addLayout(gridLayout); int comboBoxWidth = 200; QLabel* layersLabel = new QLabel(tr("Number of layers:")); layersLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); layersComboBox = new QComboBox(); QStringList layerItems; for (int i = 1; i <= 99; ++i) { layerItems << QString::number(i); } layersComboBox->addItems(layerItems); layersComboBox->setFixedWidth(comboBoxWidth); gridLayout->addWidget(layersLabel, 0, 0, Qt::AlignRight); gridLayout->addWidget(layersComboBox, 0, 1); QLabel* geoLabel = new QLabel(tr("Geometry input:")); geoLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); geometryComboBox = new QComboBox(); geometryComboBox->addItems(QStringList() << tr("1-top + n-thickness") << tr("n-thickness + 1-bottom") << tr("1-top + n-bottom") << tr("n-top + 1-bottom")); geometryComboBox->setFixedWidth(comboBoxWidth); gridLayout->addWidget(geoLabel, 1, 0, Qt::AlignRight); gridLayout->addWidget(geometryComboBox, 1, 1); QLabel* unitLabel = new QLabel(tr("Unit:")); unitLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); unitComboBox = new QComboBox(); unitComboBox->addItems(QStringList() << tr("m") << tr("cm") << tr("mm") << tr("in") << tr("0.1 in") << tr("ft") << tr("mile") << tr("km")); unitComboBox->setFixedWidth(comboBoxWidth); gridLayout->addWidget(unitLabel, 1, 2, Qt::AlignRight); gridLayout->addWidget(unitComboBox, 1, 3); gridLayout->setHorizontalSpacing(10); gridLayout->setVerticalSpacing(5); gridLayout->setContentsMargins(10, 10, 10, 10); treeWidget = new QTreeWidget(this); treeWidget->setColumnCount(3); QStringList headers; headers << tr("Name") << tr("Gaps") << ""; treeWidget->setHeaderLabels(headers); treeWidget->header()->setResizeMode(QHeaderView::Stretch); treeWidget->setStyleSheet("QTreeWidget::item { height: 20px; }"); mainLayout->addWidget(treeWidget); QHBoxLayout* hLayout = new QHBoxLayout; QPushButton* resetBT = new QPushButton(tr("Reset from analytical")); QPushButton* saveBT = new QPushButton(tr("Save")); QPushButton* cancelBT = new QPushButton(tr("Cancel")); connect(resetBT, SIGNAL(clicked()), this, SLOT(onResetButtonClicked())); connect(saveBT, SIGNAL(clicked()), this, SLOT(accept())); connect(cancelBT, SIGNAL(clicked()), this, SLOT(reject())); hLayout->addWidget(resetBT); hLayout->addStretch(); hLayout->addWidget(saveBT); hLayout->addWidget(cancelBT); mainLayout->addLayout(hLayout); connect(layersComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onLayersComboBoxChanged(int))); connect(geometryComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onGeometryComboBoxChanged(int))); connect(treeWidget, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(onItemChanged(QTreeWidgetItem*, int))); updateLayers(); } QColor nmWxGeometryLayerDlg::getLayerColor(int index) { if (index == 0) { return QColor(0, 255, 0); } int red = (index * 50) % 256; int green = 255 - (index * 30) % 256; int blue = (index * 70) % 256; return QColor(red, green, blue); } QTreeWidgetItem* nmWxGeometryLayerDlg::createLayer(int index, const QString& layerName) { QTreeWidgetItem* layer = new QTreeWidgetItem(treeWidget); layer->setText(0, layerName); layer->setBackground(0, QBrush(getLayerColor(index))); int numLayers = layersComboBox->currentIndex() + 1; if (numLayers == 1 || index < numLayers - 1) { QCheckBox* layerCheckBox = new QCheckBox(treeWidget); layerCheckBox->setCheckState(Qt::Unchecked); // 确保初始状态为未勾选 QWidget* checkBoxWidget = new QWidget(treeWidget); QHBoxLayout* checkBoxLayout = new QHBoxLayout(checkBoxWidget); checkBoxLayout->addWidget(layerCheckBox); checkBoxLayout->setAlignment(Qt::AlignCenter); checkBoxLayout->setContentsMargins(0, 0, 0, 0); treeWidget->setItemWidget(layer, 1, checkBoxWidget); connect(layerCheckBox, SIGNAL(stateChanged(int)), this, SLOT(onLayerCheckBoxStateChanged(int))); } configureLayerItems(index, layer); return layer; // 返回创建的QTreeWidgetItem } void nmWxGeometryLayerDlg::configureLayerItems(int layerIndex, QTreeWidgetItem* layerItem) { if (layerIndex < 0 || layerIndex >= m_layerData.size()) { return; } nmDataLayer* layer = m_layerData[layerIndex]; int geometryIndex = geometryComboBox->currentIndex(); if (geometryIndex == 0) { // "1-top + n-thickness" if (layerIndex == 0) { QTreeWidgetItem* top = new QTreeWidgetItem(layerItem); treeWidget->setItemWidget(top, 0, new QLabel(tr("Top"), this)); treeWidget->setItemWidget(top, 1, createComboBox(tr("Constant"))); top->setText(2, QString::number(layer->getTop(), 'f', 2)); top->setFlags(top->flags() | Qt::ItemIsEditable); } QTreeWidgetItem* thickness = new QTreeWidgetItem(layerItem); treeWidget->setItemWidget(thickness, 0, new QLabel(tr("Thickness"), this)); treeWidget->setItemWidget(thickness, 1, createComboBox(tr("Constant"))); thickness->setText(2, QString::number(layer->getThickness(), 'f', 2)); thickness->setFlags(thickness->flags() | Qt::ItemIsEditable); } else if (geometryIndex == 1) { // "n-thickness + 1-bottom" QTreeWidgetItem* thickness = new QTreeWidgetItem(layerItem); treeWidget->setItemWidget(thickness, 0, new QLabel(tr("Thickness"), this)); treeWidget->setItemWidget(thickness, 1, createComboBox(tr("Constant"))); thickness->setText(2, QString::number(layer->getThickness(), 'f', 2)); thickness->setFlags(thickness->flags() | Qt::ItemIsEditable); if (layerIndex == layersComboBox->currentIndex()) { QTreeWidgetItem* bottom = new QTreeWidgetItem(layerItem); treeWidget->setItemWidget(bottom, 0, new QLabel(tr("Bottom"), this)); treeWidget->setItemWidget(bottom, 1, createComboBox(tr("Constant"))); bottom->setText(2, QString::number(layer->getBottom(), 'f', 2)); bottom->setFlags(bottom->flags() | Qt::ItemIsEditable); } } else if (geometryIndex == 2) { // "1-top + n-bottom" if (layerIndex == 0) { QTreeWidgetItem* top = new QTreeWidgetItem(layerItem); treeWidget->setItemWidget(top, 0, new QLabel(tr("Top"), this)); treeWidget->setItemWidget(top, 1, createComboBox(tr("Constant"))); top->setText(2, QString::number(layer->getTop(), 'f', 2)); top->setFlags(top->flags() | Qt::ItemIsEditable); } QTreeWidgetItem* bottom = new QTreeWidgetItem(layerItem); treeWidget->setItemWidget(bottom, 0, new QLabel(tr("Bottom"), this)); treeWidget->setItemWidget(bottom, 1, createComboBox(tr("Constant"))); bottom->setText(2, QString::number(layer->getBottom(), 'f', 2)); bottom->setFlags(bottom->flags() | Qt::ItemIsEditable); } else if (geometryIndex == 3) { // "n-top + 1-bottom" QTreeWidgetItem* top = new QTreeWidgetItem(layerItem); treeWidget->setItemWidget(top, 0, new QLabel(tr("Top"), this)); treeWidget->setItemWidget(top, 1, createComboBox(tr("Constant"))); top->setText(2, QString::number(layer->getTop(), 'f', 2)); top->setFlags(top->flags() | Qt::ItemIsEditable); if (layerIndex == layersComboBox->currentIndex()) { QTreeWidgetItem* bottom = new QTreeWidgetItem(layerItem); treeWidget->setItemWidget(bottom, 0, new QLabel(tr("Bottom"), this)); treeWidget->setItemWidget(bottom, 1, createComboBox(tr("Constant"))); bottom->setText(2, QString::number(layer->getBottom(), 'f', 2)); bottom->setFlags(bottom->flags() | Qt::ItemIsEditable); } } } QComboBox* nmWxGeometryLayerDlg::createComboBox(const QString& defaultText) { QComboBox* comboBox = new QComboBox(treeWidget); comboBox->addItems(QStringList() << tr("Constant") << tr("Data set...")); comboBox->setCurrentIndex(comboBox->findText(defaultText)); return comboBox; } void nmWxGeometryLayerDlg::onLayerCheckBoxStateChanged(int state) { QCheckBox* senderCheckBox = qobject_cast(sender()); if (!senderCheckBox) return; // 找到复选框所在的层索引 int currentLayerIndex = -1; for (int i = 0; i < treeWidget->topLevelItemCount(); ++i) { QTreeWidgetItem* layerItem = treeWidget->topLevelItem(i); QWidget* widget = treeWidget->itemWidget(layerItem, 1); if (widget) { QCheckBox* itemCheckBox = widget->findChild(); if (itemCheckBox == senderCheckBox) { currentLayerIndex = i; break; } } } if (currentLayerIndex == -1) return; // 更新 LayerData 的 isChecked 状态 if (currentLayerIndex < m_layerData.size() && m_layerData[currentLayerIndex] != nullptr) { m_layerData[currentLayerIndex]->setIsChecked(state == Qt::Checked); } int geometryIndex = geometryComboBox->currentIndex(); if (geometryIndex == 0 || geometryIndex == 2) { // "1-top + n-thickness" 或 "1-top + n-bottom" int nextLayerIndex = currentLayerIndex + 1; if (nextLayerIndex < treeWidget->topLevelItemCount()) { QTreeWidgetItem* nextLayer = treeWidget->topLevelItem(nextLayerIndex); handleInsertTop(state, nextLayer); } } else if (geometryIndex == 1 || geometryIndex == 3) { // "n-thickness + 1-bottom" 或 "n-top + 1-bottom" QTreeWidgetItem* currentLayer = treeWidget->topLevelItem(currentLayerIndex); handleInsertBottom(state, currentLayer); } } void nmWxGeometryLayerDlg::initLayers() { int numLayers = layersComboBox->currentIndex() + 1; qDeleteAll(m_layerData); // 删除旧数据 m_layerData.clear(); double initialTop = 6000.0; // 初始顶层高度 double defaultThickness = m_pReservoir->getThickness().getValue().toDouble(); //获取储层厚度 for (int i = 0; i < numLayers; ++i) { nmDataLayer* layer = new nmDataLayer(); layer->setTop((i == 0) ? initialTop : m_layerData[i - 1]->getBottom()); layer->setThickness(defaultThickness); layer->setBottom(layer->getTop() + defaultThickness); layer->setIsChecked(false); layer->setColor(getLayerColor(i)); // 设置储层颜色 m_layerData.append(layer); } } void nmWxGeometryLayerDlg::updateLayers() { // 保存当前复选框状态 QVector checkedStates(m_layerData.size()); for (int i = 0; i < m_layerData.size(); ++i) { checkedStates[i] = m_layerData[i]->getIsChecked(); } treeWidget->clear(); for (int i = 0; i < m_layerData.size(); ++i) { QString layerName = QString(tr("Layer #%1")).arg(i + 1); QTreeWidgetItem* layerItem = createLayer(i, layerName); // 恢复复选框状态 bool isChecked = checkedStates[i]; m_layerData[i]->setIsChecked(isChecked); QWidget* widget = treeWidget->itemWidget(layerItem, 1); if (widget) { QCheckBox* checkBox = widget->findChild(); if (checkBox) { // 先清空当前复选框的状态 checkBox->setChecked(Qt::Unchecked); // 再根据 m_layerData 的 isChecked 状态重新设置复选框的状态 checkBox->setChecked(isChecked); } } } treeWidget->expandAll(); } void nmWxGeometryLayerDlg::updateLayerData(int index) { if (index < 0 || index >= m_layerData.size()) { return; } // 使用指针访问对象 nmDataLayer* currentLayer = m_layerData[index]; if (currentLayer == nullptr) { return; } currentLayer->setThickness(currentLayer->getBottom() - currentLayer->getTop()); if (index + 1 < m_layerData.size()) { nmDataLayer* nextLayer = m_layerData[index + 1]; if (nextLayer == nullptr) { return; } nextLayer->setTop(currentLayer->getBottom()); nextLayer->setBottom(nextLayer->getTop() + nextLayer->getThickness()); } QTreeWidgetItem* layerItem = treeWidget->topLevelItem(index); if (layerItem) { for (int i = 0; i < layerItem->childCount(); ++i) { QTreeWidgetItem* child = layerItem->child(i); if (child == nullptr) { continue; } QLabel* label = qobject_cast(treeWidget->itemWidget(child, 0)); if (label) { if (label->text() == tr("Top")) { child->setText(2, QString::number(currentLayer->getTop(), 'f', 2)); } else if (label->text() == tr("Bottom")) { child->setText(2, QString::number(currentLayer->getBottom(), 'f', 2)); } else if (label->text() == tr("Thickness")) { child->setText(2, QString::number(currentLayer->getThickness(), 'f', 2)); } } } } if (index + 1 < m_layerData.size()) { QTreeWidgetItem* nextLayerItem = treeWidget->topLevelItem(index + 1); if (nextLayerItem) { for (int i = 0; i < nextLayerItem->childCount(); ++i) { QTreeWidgetItem* child = nextLayerItem->child(i); if (child == nullptr || m_layerData[index + 1] == nullptr) { continue; } QLabel* label = qobject_cast(treeWidget->itemWidget(child, 0)); if (label && label->text() == tr("Top")) { child->setText(2, QString::number(m_layerData[index + 1]->getTop(), 'f', 2)); } } } } } void nmWxGeometryLayerDlg::handleInsertTop(int state, QTreeWidgetItem* layer) { if (!layer) return; if (state == Qt::Checked) { bool hasTop = false; for (int i = 0; i < layer->childCount(); ++i) { QLabel* label = qobject_cast(treeWidget->itemWidget(layer->child(i), 0)); if (label && label->text() == tr("Top")) { hasTop = true; break; } } if (!hasTop) { QTreeWidgetItem* top = new QTreeWidgetItem(); top->setFlags(top->flags() | Qt::ItemIsEditable); layer->insertChild(0, top); QLabel* nameLabel = new QLabel(tr("Top")); QComboBox* typeComboBox = createComboBox(tr("Constant")); treeWidget->setItemWidget(top, 0, nameLabel); treeWidget->setItemWidget(top, 1, typeComboBox); int layerIndex = treeWidget->indexOfTopLevelItem(layer); if (layerIndex >= 0 && layerIndex < m_layerData.size()) { top->setText(2, QString::number(m_layerData[layerIndex]->getTop(), 'f', 2)); } } } else { for (int i = 0; i < layer->childCount(); ++i) { QLabel* label = qobject_cast(treeWidget->itemWidget(layer->child(i), 0)); if (label && label->text() == tr("Top")) { delete layer->takeChild(i); break; } } } } void nmWxGeometryLayerDlg::handleInsertBottom(int state, QTreeWidgetItem* layer) { if (!layer) return; if (state == Qt::Checked) { bool hasBottom = false; for (int i = 0; i < layer->childCount(); ++i) { QLabel* label = qobject_cast(treeWidget->itemWidget(layer->child(i), 0)); if (label && label->text() == tr("Bottom")) { hasBottom = true; break; } } if (!hasBottom) { QTreeWidgetItem* bottom = new QTreeWidgetItem(layer); bottom->setFlags(bottom->flags() | Qt::ItemIsEditable); QLabel* nameLabel = new QLabel(tr("Bottom")); QComboBox* typeComboBox = createComboBox(tr("Constant")); treeWidget->setItemWidget(bottom, 0, nameLabel); treeWidget->setItemWidget(bottom, 1, typeComboBox); int layerIndex = treeWidget->indexOfTopLevelItem(layer); if (layerIndex >= 0 && layerIndex < m_layerData.size()) { bottom->setText(2, QString::number(m_layerData[layerIndex]->getBottom(), 'f', 2)); } } } else { for (int i = 0; i < layer->childCount(); ++i) { QLabel* label = qobject_cast(treeWidget->itemWidget(layer->child(i), 0)); if (label && label->text() == tr("Bottom")) { delete layer->takeChild(i); break; } } } } void nmWxGeometryLayerDlg::onItemChanged(QTreeWidgetItem* item, int column) { if (column != 2) return; // 只处理第三列的数据变化 QTreeWidgetItem* layerItem = item->parent(); if (!layerItem) return; int layerIndex = treeWidget->indexOfTopLevelItem(layerItem); bool ok; double value = item->text(2).toDouble(&ok); if (!ok) return; if (layerIndex >= 0 && layerIndex < m_layerData.size()) { nmDataLayer* currentLayer = m_layerData[layerIndex]; QLabel* label = qobject_cast(treeWidget->itemWidget(item, 0)); if (label) { if (label->text() == tr("Top")) { currentLayer->setTop(value); currentLayer->setBottom(currentLayer->getTop() + currentLayer->getThickness()); } else if (label->text() == tr("Bottom")) { currentLayer->setBottom(value); currentLayer->setThickness(currentLayer->getBottom() - currentLayer->getTop()); } else if (label->text() == tr("Thickness")) { currentLayer->setThickness(value); currentLayer->setBottom(currentLayer->getTop() + currentLayer->getThickness()); } updateLayerData(layerIndex); } // 更新后续层的 top 和 bottom for (int i = layerIndex + 1; i < m_layerData.size(); ++i) { nmDataLayer* prevLayer = m_layerData[i - 1]; nmDataLayer* nextLayer = m_layerData[i]; nextLayer->setTop(prevLayer->getBottom()); nextLayer->setBottom(nextLayer->getTop() + nextLayer->getThickness()); updateLayerData(i); } } } void nmWxGeometryLayerDlg::onLayersComboBoxChanged(int index) { int newNumLayers = index + 1; int currentNumLayers = m_layerData.size(); if (newNumLayers < currentNumLayers) { // 删除多余的层 for (int i = currentNumLayers - 1; i >= newNumLayers; --i) { delete m_layerData[i]; } m_layerData.resize(newNumLayers); } else if (newNumLayers > currentNumLayers) { double defaultThickness = 15.0; for (int i = currentNumLayers; i < newNumLayers; ++i) { nmDataLayer* newLayer = new nmDataLayer(); newLayer->setTop((i == 0) ? 6000.0 : m_layerData[i - 1]->getBottom()); newLayer->setThickness(defaultThickness); newLayer->setBottom(newLayer->getTop() + defaultThickness); newLayer->setIsChecked(false); // 默认未选中 newLayer->setColor(getLayerColor(i)); // 设置储层颜色 m_layerData.append(newLayer); } } updateLayers(); } void nmWxGeometryLayerDlg::onGeometryComboBoxChanged(int index) { updateLayers(); } void nmWxGeometryLayerDlg::onResetButtonClicked() { // 将 geometryComboBox 设置为 "1-top + n-thickness" geometryComboBox->setCurrentIndex(0); // 初始化层数据 initLayers(); // 更新层显示 updateLayers(); } QVector nmWxGeometryLayerDlg::getLayerData() const { // 返回 m_layerData 的副本 return m_layerData; }