fix(nmNum): 修复 PEBI 参数修改后的地图与网格刷新

- 增加属性实际编辑通知,避免相同值重复推进计算输入版本
- 区分网格输入与仅求解输入,按参数类型失效网格或结果
- 监听井数据变化并刷新 Map,补齐井对象替换后的信号重绑定
- GridControl 变化后通知网格窗口,并同步最新控制值
- 修复井图元刷新接口访问权限导致的编译错误
develop
lh 9 hours ago
parent 4542d1132a
commit 297775ebd0

@ -55,6 +55,10 @@ signals:
/// @brief Data→UI 方向:属性变更通知,携带 name 和新值
void sigAttrChanged(QString name, QVariant value);
/// @brief UI 已实际修改底层属性,供数据管理器推进网格或结果输入版本
/// @note 与 sigAttrChanged 分开,避免外部数据刷新 UI 时被误判为用户编辑
void sigAttrEdited(QString name, QVariant value);
private slots:
/// @brief 监听 nmDataAttribute::sigValueChanged用 sender() 反查 name

@ -26,6 +26,7 @@
#include <QList>
#include <QMutex>
#include <QSharedPointer>
#include <QVariant>
#include <QWaitCondition>
#include <vector>
@ -832,6 +833,10 @@ public:
/** @brief 并行结果快照或其结果井选择已经改变。 */
void sigPebiResultSnapshotChanged();
private slots:
/** @brief 根据参数面板实际编辑的属性类型,使对应 PEBI 输入版本失效。 */
void onRegisteredAttributeEdited(QString sName, QVariant oValue);
private:
/** @brief 按 UUID 给当前实时井统一绑定或解除最后结果快照弱引用。 */
void rebindPebiResultSnapshotToWells();

@ -187,7 +187,7 @@ public:
// 同步井图元可见性到井数据
// 更新井图元的数据映射(编辑井后更换数据对象时使用)
void updateWellDataMapping(nmObjPointWell* pGraphic, nmDataWellBase* pNewData) { m_mapWellData[pGraphic] = pNewData; }
void updateWellDataMapping(nmObjPointWell* pGraphic, nmDataWellBase* pNewData);
// 井相关数据中心委托方法
bool hasLayers() const;
@ -242,6 +242,7 @@ private slots:
// 井图元信号 → 数据同步
void onGraphicWellVisibleChanged(bool bVisible);
void onWellDataChanged();
private:
nmDataAnalyzeManager* m_pDataMgr; // 数据中心,不持有,外部注入

@ -126,10 +126,22 @@ void nmAttrRegistry::setValue(QString name, QVariant value)
return;
}
// 控件重建或失去焦点时可能重复提交相同值;此类提交不能推进计算输入版本。
const QVariant oOldValue = pAttr->getValue();
if (oOldValue == value) {
return;
}
m_bSyncing = true;
pAttr->setValue(value); // → nmDataAttribute 发 sigValueChanged
// → onAttrValueChanged 检测 m_bSyncing=true → 跳过 sigAttrChanged
m_bSyncing = false;
// 属性已完成写入后再通知数据管理器,保证监听者读取到的是最终值。
const QVariant oNewValue = pAttr->getValue();
if (oOldValue != oNewValue) {
emit sigAttrEdited(name, oNewValue);
}
}
void nmAttrRegistry::onAttrValueChanged()

@ -607,6 +607,39 @@ static bool isGeometryParaAttrName(const QString& name)
return false;
}
// 参数注册名可能带对象编码前缀,判断时只匹配完整的基础参数后缀。
static bool hasRegisteredAttributeBaseName(
const QString& sName,
const char* pBaseName)
{
const QString sBaseName = QString::fromLatin1(pBaseName);
return sName == sBaseName || sName.endsWith(QString("_") + sBaseName);
}
// 这里只区分网格输入和仅求解输入,不在界面层重新解释 PEBI 业务规则。
static bool isPebiGridInputAttributeName(const QString& sName)
{
static const char* GRID_INPUT_NAMES[] = {
"W_X", "W_Y", "W_Rw",
"W_FractureHalfLength", "W_FractureAngle", "W_Dfc",
"W_WellLength", "W_DrainAngle", "W_NumberOfFractures",
"F_X0", "F_Y0", "F_X1", "F_Y1",
"FT_X0", "FT_Y0", "FT_X1", "FT_Y1",
"BR_XMin", "BR_YMin", "BR_XMax", "BR_YMax",
"BC_CenterX", "BC_CenterY", "BC_Radius",
"BP_X", "BP_Y"
};
const int nNameCount = sizeof(GRID_INPUT_NAMES) /
sizeof(GRID_INPUT_NAMES[0]);
for(int nIndex = 0; nIndex < nNameCount; ++nIndex) {
if(hasRegisteredAttributeBaseName(sName,
GRID_INPUT_NAMES[nIndex])) {
return true;
}
}
return false;
}
namespace {
// 清空指定目录下的所有旧文件和子目录,但保留目录本身
bool clearDirectoryContents(const QString& dirPath)
@ -1329,6 +1362,8 @@ ZX_DEFINE_DYNAMIC(DataAnalyzeManager, nmDataAnalyzeManager)
// 属性注册表
m_pAttrRegistry = new nmAttrRegistry();
connect(m_pAttrRegistry, SIGNAL(sigAttrEdited(QString,QVariant)),
this, SLOT(onRegisteredAttributeEdited(QString,QVariant)));
m_backgroundImageInfo.bIsVisible = false;
// 初始化混合参数数据(Temp)
@ -4308,7 +4343,14 @@ bool nmDataAnalyzeManager::getIncludeOtherWells() const
void nmDataAnalyzeManager::setPebiGridControl(double dGridControl)
{
const quint64 nOldGridInputRevision =
m_oNumericalAnalysisCase.getGridInputRevision();
m_oNumericalAnalysisCase.setPebiGridControl(dGridControl);
if(nOldGridInputRevision !=
m_oNumericalAnalysisCase.getGridInputRevision()) {
// 分析方案已完成网格和结果失效,这里只通知已打开的网格窗口刷新。
emit dataChanged();
}
}
double nmDataAnalyzeManager::getPebiGridControl() const
@ -4811,13 +4853,29 @@ nmDataWellBase* nmDataAnalyzeManager::getCurWellData()
void nmDataAnalyzeManager::notifyDataChanged()
{
// 现有属性编辑链路尚未细分“几何变化”和“仅求解输入变化”,
// 为保证正确性先采用保守策略:任一计算数据变化都使网格失效
// 本入口用于几何、井集合等网格输入;仅影响求解的参数应调用
// invalidatePebiResults(),避免无意义地重建当前有效网格
m_oNumericalAnalysisCase.invalidateGrid();
emit dataChanged();
}
void nmDataAnalyzeManager::onRegisteredAttributeEdited(
QString sName,
QVariant oValue)
{
Q_UNUSED(oValue);
if(isPebiGridInputAttributeName(sName)) {
// 几何及离散参数变化后Map 使用数据对象重绘,网格窗口按新版本自动重建。
notifyDataChanged();
return;
}
// 其余实时注册参数均属于求解输入,只使结果过期,保留当前有效网格。
invalidatePebiResults();
}
void nmDataAnalyzeManager::notifyGeometryListChanged()
{
m_oNumericalAnalysisCase.invalidateGrid();

@ -1605,6 +1605,20 @@ void nmPlotGraphicBinder::bindWellToGraphic(nmObjPointWell* pGraphic, nmDataWell
_connectWell(pGraphic, pData);
}
void nmPlotGraphicBinder::updateWellDataMapping(
nmObjPointWell* pGraphic,
nmDataWellBase* pNewData)
{
if (!pGraphic || !pNewData) return;
// replaceWellData 已销毁旧井对象,其 QObject 连接会自动解除;这里补绑新对象。
m_mapWellData[pGraphic] = pNewData;
connect(pNewData, SIGNAL(sigWellDataChanged()),
this, SLOT(onWellDataChanged()), Qt::UniqueConnection);
// nmObjPointWell 将 update() 收窄为 protected通过公开基类接口触发虚刷新。
static_cast<nmObjBase*>(pGraphic)->update();
}
// 删除井图元前,先由数据层确认删除成功,再断开信号并清理映射。
bool nmPlotGraphicBinder::removeWellBinding(nmObjPointWell* pGraphic)
{
@ -1929,6 +1943,19 @@ void nmPlotGraphicBinder::onGraphicWellVisibleChanged(bool bVisible)
pData->setPlotVisible(bVisible);
}
void nmPlotGraphicBinder::onWellDataChanged()
{
nmDataWellBase* pData = qobject_cast<nmDataWellBase*>(sender());
if (!pData) return;
// 井图元在 paintBack 中读取实时坐标和裂缝几何,只需触发一次重绘。
nmObjPointWell* pGraphic = m_mapWellData.key(pData, nullptr);
if (pGraphic) {
// 保持与 nmGuiPlot 的现有调用方式一致,避免访问井类的 protected override。
static_cast<nmObjBase*>(pGraphic)->update();
}
}
bool nmPlotGraphicBinder::hasLayers() const
{
if (!m_pDataMgr) return false;
@ -1973,6 +2000,8 @@ void nmPlotGraphicBinder::_connectWell(nmObjPointWell* pGraphic, nmDataWellBase*
connect(pGraphic, SIGNAL(sigObjVisibleChanged(bool)),
this, SLOT(onGraphicWellVisibleChanged(bool)));
connect(pData, SIGNAL(sigWellDataChanged()),
this, SLOT(onWellDataChanged()), Qt::UniqueConnection);
m_setBoundWellGraphics.insert(pGraphic);
}
@ -1985,6 +2014,11 @@ void nmPlotGraphicBinder::_disconnectWell(nmObjPointWell* pGraphic)
disconnect(pGraphic, SIGNAL(sigObjVisibleChanged(bool)),
this, SLOT(onGraphicWellVisibleChanged(bool)));
nmDataWellBase* pData = m_mapWellData.value(pGraphic, nullptr);
if (pData) {
disconnect(pData, SIGNAL(sigWellDataChanged()),
this, SLOT(onWellDataChanged()));
}
m_setBoundWellGraphics.remove(pGraphic);
}

@ -282,6 +282,12 @@ void nmSubWndGrid::onDataManagerChanged()
if(sender() != m_pDataManager.data()) {
return;
}
// GridControl 由分析方案统一持有,刷新前同步,避免窗口把旧局部值写回。
nmDataAnalyzeManager* pDataManager = m_pDataManager.data();
if(pDataManager != nullptr) {
m_dPebiGridControl = pDataManager->getPebiGridControl();
}
updateGrid();
}

Loading…
Cancel
Save