diff --git a/Include/nmNum/nmPlot/nmObjLineMeasure.h b/Include/nmNum/nmPlot/nmObjLineMeasure.h index 93db60a..2837e6e 100644 --- a/Include/nmNum/nmPlot/nmObjLineMeasure.h +++ b/Include/nmNum/nmPlot/nmObjLineMeasure.h @@ -3,7 +3,7 @@ #include "nmObjLine.h" #include "nmPlot_global.h" -class nmDataMeasure; +class nmPlotGraphicBinder; class NM_PLOT_EXPORT nmObjLineMeasure : public nmObjLine @@ -38,10 +38,14 @@ public: virtual bool drawSelStates(QPainter* painter, QLineF& oLine) override; // 创建后被调用 virtual void afterCreated() override; + // 删除测量线数据绑定 + virtual void removeData() override; + // 注入 Binder 指针 + void setGraphicBinder(nmPlotGraphicBinder* pBinder) { m_pGraphicBinder = pBinder; } private: // 长度 double m_dLength; - nmDataMeasure* m_pMeasureData; + nmPlotGraphicBinder* m_pGraphicBinder; }; diff --git a/Include/nmNum/nmPlot/nmPlotGraphicBinder.h b/Include/nmNum/nmPlot/nmPlotGraphicBinder.h index 715e1a8..a16de03 100644 --- a/Include/nmNum/nmPlot/nmPlotGraphicBinder.h +++ b/Include/nmNum/nmPlot/nmPlotGraphicBinder.h @@ -16,6 +16,8 @@ class nmObjBase; class nmObjRoundOutline; class nmObjRectOutline; class nmObjPolygonOutline; +class nmDataMeasure; +class nmObjLineMeasure; // 图元与数据绑定协调器,由 nmGuiPlot 托管 class NM_PLOT_EXPORT nmPlotGraphicBinder : public QObject @@ -79,6 +81,15 @@ public: // 视觉属性兜底同步(画笔宽度、填充色、透明度),由边界图元在 paintBack 中调用 void syncOutlineVisual(nmObjBase* pGraphic); + // 调用:用户画完测量线后 + void createMeasureForGraphic(nmObjLineMeasure* pGraphic); + + // 调用:删除测量线图元前 + void removeMeasureBinding(nmObjLineMeasure* pGraphic); + + // 坐标同步:从数据对象读取起点终点,写回图元(拟合功能修改数据后由 paintBack 调用) + void syncMeasurePoints(nmObjLineMeasure* pGraphic); + // 切换分析时更新绑定的 DataManager,并清理旧图元的残留映射 void updateDataMgr(nmDataAnalyzeManager* pDataMgr); @@ -152,4 +163,7 @@ private: // 从边界数据对象读取值,写入图元本地副本(加载时用) void _pushOutlineDataToGraphic(nmObjBase* pGraphic, nmDataOutline* pData); + + // 测量线图元 → 数据 的映射表 + QMap m_mapMeasureData; }; diff --git a/Src/nmNum/nmPlot/nmGuiPlot.cpp b/Src/nmNum/nmPlot/nmGuiPlot.cpp index 7fc0e77..4aa05df 100644 --- a/Src/nmNum/nmPlot/nmGuiPlot.cpp +++ b/Src/nmNum/nmPlot/nmGuiPlot.cpp @@ -1269,6 +1269,10 @@ void nmGuiPlot::deleteMeasureObjects() for(int i = 0; i < measureObjs.count(); i++) { if(measureObjs[i] != nullptr) { + nmObjLineMeasure* pMeasure = dynamic_cast(measureObjs[i]); + if(pMeasure) { + pMeasure->removeData(); + } m_pPlot->removeObjByName(measureObjs[i]->getName()); } } @@ -1286,6 +1290,10 @@ void nmGuiPlot::clearPreviousMeasure() for(int i = 0; i < measureObjs.count(); i++) { if(measureObjs[i] != nullptr) { + nmObjLineMeasure* pMeasure = dynamic_cast(measureObjs[i]); + if(pMeasure) { + pMeasure->removeData(); + } m_pPlot->removeObjByName(measureObjs[i]->getName()); } } @@ -1385,6 +1393,8 @@ void nmGuiPlot::slotDeleteOneObj(QString sName, void* obj) dynamic_cast(nmObj) || dynamic_cast(nmObj)) { m_pGraphicBinder->removeOutlineBinding(nmObj); + } else if (nmObjLineMeasure* pMeasure = dynamic_cast(nmObj)) { + m_pGraphicBinder->removeMeasureBinding(pMeasure); } else { // 其他类型回退到旧方式 nmObj->removeData(); diff --git a/Src/nmNum/nmPlot/nmGuiPlotCmdHelper.cpp b/Src/nmNum/nmPlot/nmGuiPlotCmdHelper.cpp index 29cb7d1..3169076 100644 --- a/Src/nmNum/nmPlot/nmGuiPlotCmdHelper.cpp +++ b/Src/nmNum/nmPlot/nmGuiPlotCmdHelper.cpp @@ -19,6 +19,7 @@ #include "nmObjLineMeasuringScaleTool.h" #include "nmObjPointWellTool.h" #include "nmObjLineMeasureTool.h" +#include "nmObjLineMeasure.h" #include "nmGuiPlot.h" #include "nmGuiPlotCmdHelper.h" @@ -381,6 +382,14 @@ void nmGuiPlotCmdHelper::slotObjPtsFinished(QVector& vec) { pWxPlot->graphicBinder()->createOutlineForGraphic(pPolygon); } } + } else if (pTool->getNOT() == NMOT_Line_Measure) { + // 先执行 afterCreated(设置锁定、只读等属性) + pObj->afterCreated(); + // 再通过 Binder 创建数据并建立绑定 + nmObjLineMeasure* pMeasure = dynamic_cast(pObj); + if (pMeasure && pWxPlot->graphicBinder()) { + pWxPlot->graphicBinder()->createMeasureForGraphic(pMeasure); + } } else { pObj->afterCreated(); } diff --git a/Src/nmNum/nmPlot/nmObjLineMeasure.cpp b/Src/nmNum/nmPlot/nmObjLineMeasure.cpp index 87ea3e5..f9f938e 100644 --- a/Src/nmNum/nmPlot/nmObjLineMeasure.cpp +++ b/Src/nmNum/nmPlot/nmObjLineMeasure.cpp @@ -11,8 +11,7 @@ #include "ZxObjText.h" #include "nmObjLineMeasure.h" -#include "nmDataAnalyzeManager.h" -#include "nmDataMeasure.h" +#include "nmPlotGraphicBinder.h" ZX_DEFINE_DYNAMIC(nObjLineMeasure, nmObjLineMeasure) @@ -20,7 +19,7 @@ nmObjLineMeasure::nmObjLineMeasure() : nmObjLine("", NULL, NULL) { m_dLength = 0.0; - m_pMeasureData = nmDataAnalyzeManager::getCurrentInstance()->getMeasureData(); + m_pGraphicBinder = nullptr; m_sObjTag = "nObjLineMeasure"; nmObjPoint::initFlags(); m_oDot = ZxDot(DTS_Circle, QColor(255, 165, 0), 0.5f, true); @@ -35,7 +34,7 @@ nmObjLineMeasure::nmObjLineMeasure(const QString& sName, \ ZxSubAxisY* pAxisY) : nmObjLine(sName, pAxisX, pAxisY) { m_dLength = 0.0; - m_pMeasureData = nmDataAnalyzeManager::getCurrentInstance()->getMeasureData(); + m_pGraphicBinder = nullptr; m_sObjTag = "nObjLineMeasure"; nmObjPoint::initFlags(); m_oDot = ZxDot(DTS_Circle, QColor(255, 165, 0), 0.5f, true); @@ -59,8 +58,12 @@ void nmObjLineMeasure::initSubObjs() { void nmObjLineMeasure::paintBack(QPainter* painter, const ZxPaintParam& param) { Q_ASSERT(m_vecPoints.count() >= 2); - m_vecPoints[0] = m_pMeasureData->getStartPoint(); - m_vecPoints[1] = m_pMeasureData->getEndPoint(); + + // 坐标同步:拟合功能修改数据后,在绘制时将新坐标推回图元 + if (m_pGraphicBinder) { + m_pGraphicBinder->syncMeasurePoints(this); + } + QPointF pt1 = getPosOf(m_vecPoints[0]); QPointF pt2 = getPosOf(m_vecPoints[1]); QLineF oLine = QLineF(pt1, pt2); @@ -113,28 +116,19 @@ bool nmObjLineMeasure::drawSelStates(QPainter* painter, QLineF& oLine) { } void nmObjLineMeasure::afterCreated() { - // ���㳤�� - QPointF pStart = m_vecPoints[0]; - QPointF pEnd = m_vecPoints[1]; - double dLength = QLineF(pStart, pEnd).length(); - if (m_pMeasureData != nullptr && pEnd != pStart) { - m_pMeasureData->setStartPoint(pStart); - m_pMeasureData->setEndPoint(pEnd); - nmDataAttribute lenAttr = m_pMeasureData->getLength(); - lenAttr.setValue(dLength); - m_pMeasureData->setLength(lenAttr); - } - - if (m_pMeasureData != nullptr && pEnd == pStart) { - m_pMeasureData->setCurrentPoint(pStart); - nmDataAttribute lenAttr = m_pMeasureData->getLength(); - lenAttr.setValue(dLength); - m_pMeasureData->setLength(lenAttr); + if (m_pGraphicBinder) { + m_pGraphicBinder->createMeasureForGraphic(this); } this->setLockPos(true); this->setReadOnly(true); } +void nmObjLineMeasure::removeData() { + if (m_pGraphicBinder) { + m_pGraphicBinder->removeMeasureBinding(this); + } +} + void nmObjLineMeasure::onSerialize(ZxSerializer* ser) { nmObjLine::onSerialize(ser); ser->write("Length", m_dLength); diff --git a/Src/nmNum/nmPlot/nmPlotGraphicBinder.cpp b/Src/nmNum/nmPlot/nmPlotGraphicBinder.cpp index 3f773c8..f67ac96 100644 --- a/Src/nmNum/nmPlot/nmPlotGraphicBinder.cpp +++ b/Src/nmNum/nmPlot/nmPlotGraphicBinder.cpp @@ -8,6 +8,8 @@ #include "nmObjRectOutline.h" #include "nmObjPolygonOutline.h" #include "nmDataOutline.h" +#include "nmObjLineMeasure.h" +#include "nmDataMeasure.h" #include "nmObjBase.h" #include "nmDataAnalyzeManager.h" @@ -98,6 +100,7 @@ void nmPlotGraphicBinder::updateDataMgr(nmDataAnalyzeManager* pDataMgr) m_setBoundCrackGraphics.clear(); m_mapOutlineData.clear(); m_setBoundOutlineGraphics.clear(); + m_mapMeasureData.clear(); m_pDataMgr = pDataMgr; } @@ -767,3 +770,72 @@ void nmPlotGraphicBinder::onGraphicOutlineVisibleChanged(bool bVisible) m_pDataMgr->notifyDataChanged(); } } + +// 用户画完测量线后:获取数据对象并建立绑定 +void nmPlotGraphicBinder::createMeasureForGraphic(nmObjLineMeasure* pGraphic) +{ + if (!pGraphic || !m_pDataMgr) { + return; + } + + // 获取测量数据单例 + nmDataMeasure* pData = m_pDataMgr->getMeasureData(); + + // 将图元坐标推入数据 + QVector pts = pGraphic->getAllValues(); + if (pts.count() >= 2) { + QPointF pStart = pts[0]; + QPointF pEnd = pts[1]; + double dLength = QLineF(pStart, pEnd).length(); + if (pEnd != pStart) { + pData->setStartPoint(pStart); + pData->setEndPoint(pEnd); + } else { + pData->setCurrentPoint(pStart); + } + nmDataAttribute lenAttr = pData->getLength(); + lenAttr.setValue(dLength); + pData->setLength(lenAttr); + } + + // 建立映射 + m_mapMeasureData[pGraphic] = pData; + pGraphic->setGraphicBinder(this); + + m_pDataMgr->notifyDataChanged(); +} + +// 删除测量线图元:移除映射(不删除数据对象,由 DataManager 管理) +void nmPlotGraphicBinder::removeMeasureBinding(nmObjLineMeasure* pGraphic) +{ + if (!pGraphic) { + return; + } + + m_mapMeasureData.remove(pGraphic); +} + +// 坐标同步:从数据对象读取起点终点,写回图元(拟合功能修改数据后由 paintBack 调用) +void nmPlotGraphicBinder::syncMeasurePoints(nmObjLineMeasure* pGraphic) +{ + if (!pGraphic || !m_pDataMgr) return; + + nmDataMeasure* pData = m_mapMeasureData.value(pGraphic, nullptr); + if (!pData) return; + + QPointF startPt = pData->getStartPoint(); + QPointF endPt = pData->getEndPoint(); + + // 仅在坐标确实变化时才更新,避免每次绘制都无谓写入 + QVector currentPts = pGraphic->getAllValues(); + if (currentPts.count() >= 2 && + currentPts[0] == startPt && currentPts[1] == endPt) { + return; + } + + pGraphic->blockSignals(true); + QVector pts; + pts << startPt << endPt; + pGraphic->setAllValues(pts); + pGraphic->blockSignals(false); +}