#include "TransparentGroupResult.h" #include "TransparentDraggableResult.h" extern double g_dPixelPerCm;//每厘米像素数 TransparentGroupResult::TransparentGroupResult(QMyCustomPlot *parentPlot, TransparentGroupResult *upDraggableResult, QString strUuid, double minWidth, QString strTitle) : QObject(parentPlot), mPlot(parentPlot), mstrTitle(strTitle), mMinWidth(minWidth) { m_strUuid = strUuid; // initRect(); } TransparentGroupResult::~TransparentGroupResult() { if(mPlot) { // mPlot->removeItem(mRect); // mPlot->removeItem(mLeftHandle); // mPlot->removeItem(mRightHandle); } } void TransparentGroupResult::addResultToPlot(double left_Low, double right_Hight, QString myResult, QString &strUuid) { //获取上方Rect TransparentDraggableResult *upDragRect = nullptr; if (strUuid != "") { upDragRect = (TransparentDraggableResult *)m_mapDraggable_Result[strUuid]; } strUuid = getUUid(); // 在初始化代码中 TransparentDraggableResult *dragRect = new TransparentDraggableResult(mPlot, upDragRect, strUuid); //图片,提前设值,后面setRange改变 dragRect->setResult(myResult); // 设置初始范围 dragRect->setRange(left_Low, right_Hight); // 可选:设置颜色 //dragRect->setColor(QColor(255, 0, 0, 80)); // 半透明红色 //最小宽度 dragRect->setMinWidth(0.1); //dragRect->setTitle(strText); m_vecResult << strUuid; m_mapDraggable_Result[strUuid] = dragRect; } //设置最小宽度 void TransparentGroupResult::setMinWidth(double minWidth) { mMinWidth = minWidth; } //设置标题 void TransparentGroupResult::setTitle(QString strTitle) { mstrTitle = strTitle; mItemTitle->setText(mstrTitle); //mPlot->replot(); } //设置解释结论 void TransparentGroupResult::setResult(QString filePath) { m_Result = filePath; } // 设置矩形范围 void TransparentGroupResult::setRange(double left_Low, double right_Hight) { if(left_Low >= right_Hight) return; double lY1 = mPlot->yAxis->range().lower;//+10 double lY2 = (mPlot->yAxis->range().upper-mPlot->yAxis->range().lower)/2; mRect->topLeft->setCoords(left_Low, lY1); mRect->bottomRight->setCoords(right_Hight, mPlot->yAxis->range().upper); mItemTitle->position->setCoords((mRect->topLeft->coords().x() + mRect->bottomRight->coords().x())/2, lY2 + lY2/2); updateHandles(); } void TransparentGroupResult::setDragRange(double left_Low, double right_Hight) { if (left_Low >= right_Hight) return; double lY1 = mPlot->yAxis->range().lower;//+10 double lY2 = (mPlot->yAxis->range().upper - mPlot->yAxis->range().lower) / 2; mDragRect->topLeft->setCoords(left_Low, lY1); mDragRect->bottomRight->setCoords(right_Hight, mPlot->yAxis->range().upper); } // 获取当前范围 QCPRange TransparentGroupResult::getRange() { return QCPRange(mRect->topLeft->coords().x(), mRect->bottomRight->coords().x()); } // 删除框图 void TransparentGroupResult::deleteRect() { if(mPlot) { mPlot->m_mapDraggable_Result.remove(m_strUuid); mPlot->removeItem(mRect); mPlot->removeItem(mLeftHandle); mPlot->removeItem(mRightHandle); mPlot->removeItem(mItemTitle); mPlot->replot(); this->deleteLater(); } } void TransparentGroupResult::setSelectRect(bool bselect) { if (bselect) { mRect->setBrush(QColor(255, 0, 0, 80)); mRect->setPen(QPen(Qt::black, 1, Qt::DashLine)); } else { mRect->setBrush(Qt::NoBrush); mRect->setPen(Qt::NoPen); } mPlot->replot(); } int TransparentGroupResult::getCursor() { if (m_bMoveRect) { return 2; } if (m_bArrow) { return 1; } return 0; } void TransparentGroupResult::initRect() { // 创建透明矩形 mDragRect = new QCPItemRect(mPlot); mDragRect->setLayer("overlay"); // 确保在最上层 mDragRect->setBrush(Qt::NoBrush); mDragRect->setPen(QPen(Qt::red, 1, Qt::DashDotDotLine)); mDragRect->setVisible(false); mDragLine = new QCPItemStraightLine(mPlot); mDragLine->setPen(QPen(Qt::red, 1)); mDragLine->setVisible(false); // 创建透明矩形 mRect = new QCPItemRect(mPlot); mRect->setLayer("overlay"); // 确保在最上层 mRect->setBrush(Qt::NoBrush); mRect->setPen(Qt::NoPen); // 创建左右边界控制点 mLeftHandle = new QCPItemRect(mPlot); mLeftHandle->setLayer("overlay"); mLeftHandle->setBrush(Qt::NoBrush); mLeftHandle->setPen(Qt::NoPen); mRightHandle = new QCPItemRect(mPlot); mRightHandle->setLayer("overlay"); mRightHandle->setBrush(Qt::NoBrush); mRightHandle->setPen(Qt::NoPen); // 连接鼠标事件 connect(mPlot, &QCustomPlot::mousePress, this, &TransparentGroupResult::onMousePress); connect(mPlot, &QCustomPlot::mouseMove, this, &TransparentGroupResult::onMouseMove); connect(mPlot, &QCustomPlot::mouseRelease, this, &TransparentGroupResult::onMouseRelease); // mPixmap = new QCPItemPixmap(mPlot); // //mPixmap->setPixmap(QPixmap(":/image/file.png")); // 设置图片 // mPixmap->setScaled(true, Qt::IgnoreAspectRatio); // 设置缩放方式 // mPixmap->setLayer("overlay"); // 确保在最上层 // QPen pen = QPen(Qt::black); // pen.setWidth(1); // mPixmap->setPen(pen); mItemTitle = new QCPItemText(mPlot); mItemTitle->setText(mstrTitle); //mItemTitle->setBrush(QBrush(Qt::red)); mItemTitle->setFont(QFont("Arial", 12, QFont::Bold)); mItemTitle->setColor(Qt::black); mItemTitle->setPositionAlignment(Qt::AlignTop | Qt::AlignHCenter); mItemTitle->position->setType(QCPItemPosition::ptPlotCoords); //mItemTitle->position->setType(QCPItemPosition::ptAxisRectRatio); mItemTitle->position->setCoords(0.5, 0); mItemTitle->setLayer("overlay"); } void TransparentGroupResult::updateHandles() { // 左边界矩形控制点 mLeftHandle->topLeft->setParentAnchor(mRect->topLeft); mLeftHandle->bottomRight->setParentAnchor(mRect->topRight);//(mRect->bottomLeft); mLeftHandle->topLeft->setCoords(-0.5, 0.5); // 矩形大小 mLeftHandle->bottomRight->setCoords(0.5, -0.5); // 矩形大小 // 右边界矩形控制点 mRightHandle->topLeft->setParentAnchor(mRect->bottomLeft); mRightHandle->bottomRight->setParentAnchor(mRect->bottomRight); mRightHandle->topLeft->setCoords(-0.5, 0.5); // 矩形大小 mRightHandle->bottomRight->setCoords(0.5, -0.5); // 矩形大小 } TransparentDraggableResult* TransparentGroupResult::getSelectItemResult(QPoint pt) { TransparentDraggableResult* pret = NULL; QObjectList objList = m_mapDraggable_Result.values(); for (int i = 0; i < objList.size(); i++) { TransparentDraggableResult* p = qobject_cast(objList.at(i)); if (p && p->getLeftHandle()) { if (p->getLeftHandle()->selectTest(pt, false) < 5) { pret = p; break; } } } return pret; } void TransparentGroupResult::onDelRect() { //mDragMode = DragNone; //删除框图 deleteRect(); } void TransparentGroupResult::onMousePress(QMouseEvent *event) { event->accept(); if (event->button() == Qt::LeftButton) { double y = mPlot->xAxis->pixelToCoord(event->pos().y());//x轴展示深度 QCPRange currentRange = getRange(); if (mLeftHandle->selectTest(event->pos(), false) < 5) { mDragMode = DragLeft; } else if (mRightHandle->selectTest(event->pos(), false) < 5) { mDragMode = DragRight; } else { TransparentDraggableResult* p = this->getSelectItemResult(event->pos()); if (p) { m_pDragResult = p; mDragMode = DragItem; currentRange = p->getRange(); } else if (y >= currentRange.lower && y <= currentRange.upper) { mDragMode = DragRect; } else { mDragMode = DragNone; setSelectRect(false); return; } } setSelectRect(true); //mDragStartX = x; mDragStartY = y; mDragStartRange = currentRange; } } void TransparentGroupResult::onMouseMove_in(QMouseEvent *event) { //double x = mPlot->xAxis->pixelToCoord(event->pos().x()); //double dx = x - mDragStartX; double y = mPlot->xAxis->pixelToCoord(event->pos().y()); double dy = y - mDragStartY; QCPRange newRange = mDragStartRange; switch(mDragMode) { case DragLeft: { //double proposedLeft = mDragStartRange.lower + dx; double proposedLeft = mDragStartRange.lower + dy; // 确保不超出轴范围且不使宽度小于最小值 newRange.lower = proposedLeft; break; } case DragRight: { //double proposedRight = mDragStartRange.upper + dx; double proposedRight = mDragStartRange.upper + dy; // 确保不超出轴范围且不使宽度小于最小值 newRange.upper = proposedRight; break; } case DragItem: { break; } case DragRect: { double width = mDragStartRange.size(); //double center = mDragStartRange.center() + dx; double center = mDragStartRange.center() + dy; newRange.lower = center - width/2; newRange.upper = center + width/2; break; } default: break; } // 最终确保宽度不小于最小值(针对整体拖动的情况) if(newRange.size() < mMinWidth) { if(mDragMode == DragRect) { // 如果是整体拖动,保持中心点不变 double center = newRange.center(); newRange.lower = center - mMinWidth/2; newRange.upper = center + mMinWidth/2; } else { // 如果是边界拖动,强制设置最小宽度 if(mDragMode == DragLeft) { newRange.lower = newRange.upper - mMinWidth; } else if(mDragMode == DragRight) { newRange.upper = newRange.lower + mMinWidth; } } } if (abs(dy) > 0.2) { if (mDragMode == DragItem) { mDragLine->setVisible(true); mDragLine->point1->setCoords(mDragStartRange.upper+dy, 0); mDragLine->point2->setCoords(mDragStartRange.upper+dy, 1); } else { mDragRect->setVisible(true); setDragRange(newRange.lower, newRange.upper); } } //setRange(newRange.lower, newRange.upper); } void TransparentGroupResult::onMouseMove(QMouseEvent *event) { if (mDragMode == DragRect) { m_bMoveRect = true; } else if (mLeftHandle->selectTest(event->pos(), false) < 5 || mRightHandle->selectTest(event->pos(), false) < 5 || this->getSelectItemResult(event->pos()) || (mDragMode > DragNone && mDragMode <= DragItem)) { m_bArrow = true; m_bMoveRect = false; } else { m_bArrow = false; m_bMoveRect = false; } if(mDragMode == DragNone) return; event->accept(); onMouseMove_in(event); //后面统一刷新上方和下方rect mPlot->replot(); } void TransparentGroupResult::onMouseRelease_in(QMouseEvent *event) { if(event->button() == Qt::LeftButton && mDragMode != DragNone) { event->accept(); //避免二次绘制框图 mPlot->m_bDrawRect = false; //emit rangeChanged(getRange()); mDragMode = DragNone; } } void TransparentGroupResult::onMouseRelease(QMouseEvent *event) { if(event->button() == Qt::LeftButton && mDragMode != DragNone) { if (mDragRect->visible()) { double y = mPlot->xAxis->pixelToCoord(event->pos().y()); double dy = y - mDragStartY; QCPRange newRange = mDragStartRange; switch (mDragMode) { case DragLeft: { //double proposedLeft = mDragStartRange.lower + dx; double proposedLeft = mDragStartRange.lower + dy; // 确保不超出轴范围且不使宽度小于最小值 newRange.lower = qBound( //mPlot->xAxis->range().lower, getMyLower(), proposedLeft, mDragStartRange.upper - mMinWidth); break; } case DragRight: { //double proposedRight = mDragStartRange.upper + dx; double proposedRight = mDragStartRange.upper + dy; // 确保不超出轴范围且不使宽度小于最小值 newRange.upper = qBound( mDragStartRange.lower + mMinWidth, proposedRight, getMyUpper()); //mPlot->xAxis->range().upper); break; } case DragRect: { double width = mDragStartRange.size(); //double center = mDragStartRange.center() + dx; double center = mDragStartRange.center() + dy; newRange.lower = center - width / 2; newRange.upper = center + width / 2; // 检查是否超出轴范围 if (newRange.lower < getMyLower()) { newRange.lower = getMyLower(); newRange.upper = newRange.lower + width; } else if (newRange.upper > getMyUpper()) { newRange.upper = getMyUpper(); newRange.lower = newRange.upper - width; } break; } default: break; } // 最终确保宽度不小于最小值(针对整体拖动的情况) if (newRange.size() < mMinWidth) { if (mDragMode == DragRect) { // 如果是整体拖动,保持中心点不变 double center = newRange.center(); newRange.lower = center - mMinWidth / 2; newRange.upper = center + mMinWidth / 2; } else { // 如果是边界拖动,强制设置最小宽度 if (mDragMode == DragLeft) { newRange.lower = newRange.upper - mMinWidth; } else if (mDragMode == DragRight) { newRange.upper = newRange.lower + mMinWidth; } } } mDragRect->setVisible(false); mDragLine->setVisible(false); setRange(newRange.lower, newRange.upper); if (m_vecResult.size() == 1) { TransparentDraggableResult* pret = qobject_cast(m_mapDraggable_Result.value(m_vecResult.at(0))); if (pret) { pret->setRange(newRange.lower, newRange.upper); } } else { if (mDragMode == DragRect) { float offset = mDragStartRange.lower - getRange().lower; for (int i = 0; i < m_vecResult.size(); i++) { TransparentDraggableResult* pret = qobject_cast(m_mapDraggable_Result.value(m_vecResult.at(i))); if (pret == NULL) continue; QCPRange rg = pret->getRange(); pret->setRange(rg.lower - offset, rg.upper - offset); } } else { TransparentDraggableResult* pret = qobject_cast(m_mapDraggable_Result.value(m_vecResult.at(0))); if (pret) { pret->setRange(pret->getRange().lower, newRange.upper); } pret = qobject_cast(m_mapDraggable_Result.value(m_vecResult.last())); if (pret) { pret->setRange(newRange.lower, pret->getRange().upper); } } } } else if (mDragLine->visible()) { if (mDragMode == DragItem) { if (m_pDragResult) { double y = mPlot->xAxis->pixelToCoord(event->pos().y()); double dy = y - mDragStartY; QCPRange rg = m_pDragResult->getRange(); m_pDragResult->setRange(rg.lower, rg.upper + dy); TransparentDraggableResult* upr = m_pDragResult->getUpResult(); if (upr) { QCPRange rg = upr->getRange(); upr->setRange(rg.lower + dy, rg.upper); } m_pDragResult = NULL; } mDragLine->setVisible(false); } } mPlot->replot(); } onMouseRelease_in(event); } double TransparentGroupResult::getMyLower() { double dLower = mPlot->xAxis->range().lower; double proposedLeft = mDragStartRange.lower; TransparentGroupResult *pDraggableRect =NULL; { QMap::Iterator it = mPlot->m_mapDragGroup.begin(); while( it != mPlot->m_mapDragGroup.end() ) { if(it.key() == m_strUuid) { it++; continue; } pDraggableRect = (TransparentGroupResult*)it.value(); // QCPRange tmpRange = pDraggableRect->getRange(); if(tmpRange.upper >= dLower && tmpRange.upper <= proposedLeft) { dLower = tmpRange.upper; } it++; } } return dLower; } double TransparentGroupResult::getMyUpper() { double dUpper = mPlot->xAxis->range().upper; double proposedRight = mDragStartRange.upper; TransparentGroupResult *pDraggableRect =NULL; { QMap::Iterator it = mPlot->m_mapDragGroup.begin(); while( it != mPlot->m_mapDragGroup.end() ) { if(it.key() == m_strUuid) { it++; continue; } pDraggableRect = (TransparentGroupResult*)it.value(); // QCPRange tmpRange = pDraggableRect->getRange(); if(tmpRange.lower <= dUpper && tmpRange.lower >= proposedRight) { dUpper = tmpRange.lower; } it++; } } return dUpper; }