#ifndef TRANSPARENTDRAGGABLERESUL_H #define TRANSPARENTDRAGGABLERESUL_H #include #include "qmycustomplot.h" #include #include #include "geometryutils.h" #include #pragma execution_character_set("utf-8") // 强制指定执行字符集为 UTF-8 class TransparentDraggableResult : public QObject { Q_OBJECT public: explicit TransparentDraggableResult(QMyCustomPlot *parentPlot, TransparentDraggableResult *upDraggableResult=nullptr, QString strUuid="", double minWidth = 1.0, QString strTitle = "") : QObject(parentPlot), mPlot(parentPlot), mstrTitle(strTitle), mMinWidth(minWidth) { m_upDraggableResult = upDraggableResult; m_strUuid = strUuid; // initRect(); //将自己,设置为上方rect的下方 if(m_upDraggableResult) { m_upDraggableResult->m_downDraggableResult = this; } } ~TransparentDraggableResult() { if(mPlot) { // mPlot->removeItem(mRect); // mPlot->removeItem(mLeftHandle); // mPlot->removeItem(mRightHandle); } } void DrawSVGNormal(QPainter* painter,QString svgFileName,QRectF borderRect,bool IsWellSectonHorizonLayout) { QString svg=svgFileName; QRectF boundingRect = painter->transform().mapRect(borderRect); painter->save(); QTransform transform; transform.reset(); if (!IsWellSectonHorizonLayout) { painter->setWorldTransform(transform); } else { } QPixmap tiledmap(svg); QRect border(boundingRect.left(),boundingRect.top(),boundingRect.width(),boundingRect.height()); painter->drawPixmap(border,tiledmap); painter->restore(); } //拉伸 void DrawSVGSteched(QPainter* painter,QString svgFileName,QRectF borderRect,bool IsWellSectonHorizonLayout) { QString svg=svgFileName; QSvgRenderer m_SvgRenderer; m_SvgRenderer.load(svg); m_SvgRenderer.render(painter,borderRect); } //平铺 void DrawSVGTiled(QPainter* painter,QString svgFileName,QRectF borderRect,bool IsWellSectonHorizonLayout) { QString svg=svgFileName; QRectF boundingRect = painter->transform().mapRect(borderRect); painter->save(); QTransform transform; transform.reset(); if (!IsWellSectonHorizonLayout) { painter->setWorldTransform(transform); } else { } QPixmap tiledmap(svg); painter->drawTiledPixmap(boundingRect,tiledmap); painter->restore(); } //设置最小宽度 void setMinWidth(double minWidth){ mMinWidth = minWidth; } //设置标题 void setTitle(QString strTitle){ mstrTitle = strTitle; mItemTitle->setText(mstrTitle); mPlot->replot(); } //设置解释结论 void setResult(QString filePath){ m_Result = filePath; // QString strLast = filePath.right(4); if(strLast.toLower()==".svg") { QString path,filename; GetWellNameAndPath(filePath, filename, path); QString basename = filename.left(filename.size()-4); QString val=filePath; QImage image(320,160,QImage::Format_RGB32); QPainter painter(&image); QRectF fillRect(0,0,320,160); painter.fillRect(fillRect,Qt::white); //拉伸 DrawSVGSteched(&painter,filePath,fillRect,0); //平铺 //DrawSVGTiled(&painter,filePath,fillRect,0); //正常 //DrawSVGNormal(&painter,filePath,fillRect,0); val=GetImagePath()+"TempNew"; QDir ss; if(!ss.exists(val)) { ss.mkdir(val); } val+=QDir::separator(); val+=basename+".png"; image.save(val); // mPixmap->setPixmap(QPixmap(val)); // 设置图片 // QSvgRenderer* svgRender = new QSvgRenderer(); // svgRender->load(result); // // // QPixmap* pixmap = new QPixmap(10, 10); // pixmap->fill(Qt::transparent);//设置背景透明 // QPainter p(pixmap); // svgRender->render(&p); // // // mPixmap->setPixmap(*pixmap); // 设置图片 } else { mPixmap->setPixmap(QPixmap(filePath)); // 设置图片 } mPlot->replot(); } // 设置矩形范围 void 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/4; mRect->topLeft->setCoords(left_Low, lY1); mRect->bottomRight->setCoords(right_Hight, lY2); //位置与rect不一样,否则图像反转 mPixmap->topLeft->setCoords(right_Hight, lY1); mPixmap->bottomRight->setCoords(left_Low, lY2); //mItemTitle->position->setCoords(0.5, 0.5); // 设置父锚点,定位点 //mItemTitle->position->setParentAnchor(mRect->bottom); //mItemTitle->position->setCoords((mRect->topLeft->coords().x() + mRect->bottomRight->coords().x())/2, // (mRect->topLeft->coords().y() + mRect->bottomRight->coords().y())/2); // 设置文本在矩形中心位置 mItemTitle->position->setCoords((mRect->topLeft->coords().x() + mRect->bottomRight->coords().x())/2, lY2 + lY2/2); //mRect->topLeft->setCoords(left, mPlot->yAxis->range().upper); //mRect->bottomRight->setCoords(right, mPlot->yAxis->range().lower); updateHandles(); //后面统一刷新上方和下方rect //mPlot->replot(); } // 获取当前范围 QCPRange getRange() const { return QCPRange(mRect->topLeft->coords().x(), mRect->bottomRight->coords().x()); } // 设置矩形颜色 void setColor(const QColor &color) { mRect->setBrush(QBrush(color)); mRect->setPen(QPen(color.darker())); mPlot->replot(); } // 删除框图 void deleteRect() { if(mPlot) { // mRect->deleteLater(); // mLeftHandle->deleteLater(); // mRightHandle->deleteLater(); // mPixmap->deleteLater(); mPlot->m_mapDraggable_Result.remove(m_strUuid); mPlot->removeItem(mRect); mPlot->removeItem(mLeftHandle); mPlot->removeItem(mRightHandle); mPlot->removeItem(mPixmap); mPlot->removeItem(mItemTitle); mPlot->replot(); this->deleteLater(); // // //避免二次绘制框图 // mPlot->m_bDrawRect = false; // mDragMode = DragNone; // //取消选中框 // mPlot->selectionRect()->cancel(); // mPlot->replot(); // mPlot->selectionRect()->mActive=true; } } signals: void rangeChanged(QCPRange newRange); private: void initRect() { // 创建透明矩形 mRect = new QCPItemRect(mPlot); mRect->setLayer("overlay"); // 确保在最上层 mRect->setBrush(QBrush(QColor(100, 100, 255, 50))); // 半透明蓝色 mRect->setPen(QPen(QColor(70, 70, 255, 200))); // 创建左右边界控制点 mLeftHandle = new QCPItemRect(mPlot); mLeftHandle->setLayer("overlay"); mLeftHandle->setBrush(QBrush(Qt::red)); mLeftHandle->setPen(QPen(Qt::darkRed)); mRightHandle = new QCPItemRect(mPlot); mRightHandle->setLayer("overlay"); mRightHandle->setBrush(QBrush(Qt::red)); mRightHandle->setPen(QPen(Qt::darkRed)); // 设置初始位置 //double center = mPlot->xAxis->range().center(); // setRange(center - 10, center + 10); // 连接鼠标事件 connect(mPlot, &QCustomPlot::mousePress, this, &TransparentDraggableResult::onMousePress); connect(mPlot, &QCustomPlot::mouseMove, this, &TransparentDraggableResult::onMouseMove); connect(mPlot, &QCustomPlot::mouseRelease, this, &TransparentDraggableResult::onMouseRelease); mPixmap = new QCPItemPixmap(mPlot); //mPixmap->setPixmap(QPixmap(":/image/file.png")); // 设置图片 mPixmap->setScaled(true, Qt::IgnoreAspectRatio); // 设置缩放方式 mPixmap->setLayer("overlay"); // 确保在最上层 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 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); // 矩形大小 // if(m_upDraggableResult) // { // // 右边界矩形控制点 // m_upDraggableResult->mLeftHandle->topLeft->setParentAnchor(mRect->bottomLeft); // m_upDraggableResult->mLeftHandle->bottomRight->setParentAnchor(mRect->bottomRight); // m_upDraggableResult->mLeftHandle->topLeft->setCoords(-5, 5); // 矩形大小 // m_upDraggableResult->mLeftHandle->bottomRight->setCoords(5, -5); // 矩形大小 // // 右边界矩形控制点 // //mRect->topLeft->setParentAnchor(m_upDraggableResult->mRect->bottomLeft); // //m_upDraggableResult->mRect->topRight->setParentAnchor(mRect->bottomRight); // // mRect->topLeft->setParentAnchor(m_upDraggableResult->mRect->bottomLeft); // // mRect->bottomRight->setParentAnchor(m_upDraggableResult->mRect->bottomRight); // } } private slots: void onDelRect() { //mDragMode = DragNone; //删除框图 deleteRect(); } // 事件过滤器处理函数 // bool eventFilter(QObject* object, QEvent* event) { // if (event->type() == QEvent::MouseButtonPress) { // // 拦截操作 // return true; // 阻止事件传递 //// if (object == action) { //// // 验证权限 //// if (1) { //// // 允许操作 //// action->trigger(); //// } else { //// // 拦截操作 //// return true; // 阻止事件传递 //// } //// } // } // return false; // 默认不拦截其他事件 // } void onMousePress(QMouseEvent *event) { // //右键 // 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 = DragNone; // } // else if(mRightHandle->selectTest(event->pos(), false) < 5) { // mDragMode = DragNone; // } // //else if(x >= currentRange.lower && x <= currentRange.upper) { // else if(y >= currentRange.lower && y <= currentRange.upper) { // mDragMode = DragNone; // } // else { // mDragMode = DragNone; // return; // } // //event->accept(); // QMenu menu(nullptr); // QAction *delAction = menu.addAction("删除框图"); // //delAction->installEventFilter(this); // connect(delAction, &QAction::triggered, this, &TransparentDraggableResult::onDelRect); // QAction* pItem = menu.exec(event->globalPos()); // if(pItem == delAction) // { // //event->accept(); // int ii=0; // ii++; // } // menu.exec(event->globalPos()); // return; // } event->accept(); // 检查点击了哪个部分 //double x = mPlot->xAxis->pixelToCoord(event->pos().x()); //double y = mPlot->yAxis->pixelToCoord(event->pos().y()); 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 if(x >= currentRange.lower && x <= currentRange.upper) { else if(y >= currentRange.lower && y <= currentRange.upper) { mDragMode = DragRect; } else { mDragMode = DragNone; return; } //mDragStartX = x; mDragStartY = y; mDragStartRange = currentRange; //上方rect同步动 if(m_upDraggableResult) { if(mDragMode==DragRight || mDragMode==DragRect) { m_upDraggableResult->mDragMode = DragLeft; m_upDraggableResult->mDragStartY = y; m_upDraggableResult->mDragStartRange = m_upDraggableResult->getRange(); } } //下方rect同步动 if(m_downDraggableResult) { if(mDragMode==DragLeft || mDragMode==DragRect) { m_downDraggableResult->mDragMode = DragRight; m_downDraggableResult->mDragStartY = y; m_downDraggableResult->mDragStartRange = m_downDraggableResult->getRange(); } } } void 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 = 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; } // QCPRange axisRange = mPlot->xAxis->range(); // if(newRange.lower < axisRange.lower) { // newRange.lower = axisRange.lower; // newRange.upper = newRange.lower + width; // } // else if(newRange.upper > axisRange.upper) { // newRange.upper = axisRange.upper; // newRange.lower = newRange.upper - width; // } break; } default: break; } // //取整数(方便显示统计,左右边界整数显示。) // newRange.lower = (int)newRange.lower; // QCPRange rangeByFile = mPlot->xAxis->range(); // if (std::fabs(rangeByFile.upper - (int)newRange.upper) >= 1.0) // { // newRange.upper = (int)newRange.upper; // } // 最终确保宽度不小于最小值(针对整体拖动的情况) 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; } } } setRange(newRange.lower, newRange.upper); } void onMouseMove_in_DragLeft(QMouseEvent *event) { double y = mPlot->xAxis->pixelToCoord(event->pos().y()); double dy = y - mDragStartY; QCPRange newRange = mDragStartRange; double proposedLeft = mDragStartRange.lower + dy; // 确保不超出轴范围且不使宽度小于最小值 newRange.lower = qBound( getMyLower(), proposedLeft, mDragStartRange.upper - mMinWidth); // 最终确保宽度不小于最小值(针对整体拖动的情况) if(newRange.size() < mMinWidth) { newRange.lower = newRange.upper - mMinWidth; } setRange(newRange.lower, newRange.upper); } void onMouseMove_in_DragRight(QMouseEvent *event) { double y = mPlot->xAxis->pixelToCoord(event->pos().y()); double dy = y - mDragStartY; QCPRange newRange = mDragStartRange; double proposedRight = mDragStartRange.upper + dy; // 确保不超出轴范围且不使宽度小于最小值 newRange.upper = qBound( mDragStartRange.lower + mMinWidth, proposedRight, getMyUpper()); // 最终确保宽度不小于最小值(针对整体拖动的情况) if(newRange.size() < mMinWidth) { newRange.upper = newRange.lower + mMinWidth; } setRange(newRange.lower, newRange.upper); } void onMouseMove(QMouseEvent *event) { if(mDragMode == DragNone) return; event->accept(); onMouseMove_in(event); //上方rect同步动 if(m_upDraggableResult) { if(mDragMode==DragRight || mDragMode==DragRect) { //m_upDraggableResult->mDragMode = DragLeft; m_upDraggableResult->onMouseMove_in_DragLeft(event); } } //下方rect同步动 if(m_downDraggableResult) { if(mDragMode==DragLeft || mDragMode==DragRect) { //m_downDraggableResult->mDragMode = DragRight; m_downDraggableResult->onMouseMove_in_DragRight(event); } } //后面统一刷新上方和下方rect mPlot->replot(); } void onMouseRelease_in(QMouseEvent *event) { if(event->button() == Qt::LeftButton && mDragMode != DragNone) { event->accept(); //避免二次绘制框图 mPlot->m_bDrawRect = false; //emit rangeChanged(getRange()); mDragMode = DragNone; //取消选中状态 // QCPDataSelection emptySelection; // mPlot->graph(0)->setSelection(emptySelection); // mPlot->replot(); // //取消选中框 // mPlot->selectionRect()->cancel(); // mPlot->replot(); // mPlot->selectionRect()->mActive=true; } } void onMouseRelease(QMouseEvent *event) { if(event->button() == Qt::LeftButton && mDragMode != DragNone) { //上方rect同步动 if(m_upDraggableResult) { if(mDragMode==DragRight || mDragMode==DragRect) { m_upDraggableResult->onMouseRelease_in(event); } } //下方rect同步动 if(m_downDraggableResult) { if(mDragMode==DragLeft || mDragMode==DragRect) { m_downDraggableResult->onMouseRelease_in(event); } } } onMouseRelease_in(event); } double getMyLower() { double dLower = mPlot->xAxis->range().lower; double proposedLeft = mDragStartRange.lower; TransparentDraggableResult *pDraggableRect =NULL; { QMap::Iterator it = mPlot->m_mapDraggable_Result.begin(); while( it != mPlot->m_mapDraggable_Result.end() ) { if(it.key() == m_strUuid) { it++; continue; } pDraggableRect = (TransparentDraggableResult*)it.value(); // QCPRange tmpRange = pDraggableRect->getRange(); if(tmpRange.upper >= dLower && tmpRange.upper <= proposedLeft) { dLower = tmpRange.upper; } it++; } } return dLower; } double getMyUpper() { double dUpper = mPlot->xAxis->range().upper; double proposedRight = mDragStartRange.upper; TransparentDraggableResult *pDraggableRect =NULL; { QMap::Iterator it = mPlot->m_mapDraggable_Result.begin(); while( it != mPlot->m_mapDraggable_Result.end() ) { if(it.key() == m_strUuid) { it++; continue; } pDraggableRect = (TransparentDraggableResult*)it.value(); // QCPRange tmpRange = pDraggableRect->getRange(); if(tmpRange.lower <= dUpper && tmpRange.lower >= proposedRight) { dUpper = tmpRange.lower; } it++; } } return dUpper; } private: QMyCustomPlot *mPlot; QCPItemRect *mRect; QCPItemRect *mLeftHandle; QCPItemRect *mRightHandle; QCPItemPixmap *mPixmap; QCPItemText *mItemTitle; QString mstrTitle=""; QString m_strUuid = ""; TransparentDraggableResult *m_upDraggableResult=nullptr; TransparentDraggableResult *m_downDraggableResult=nullptr; QString m_Result; enum DragMode { DragNone, DragLeft, DragRight, DragRect }; DragMode mDragMode = DragNone; //double mDragStartX = 0; double mDragStartY = 0; QCPRange mDragStartRange; // 添加最小宽度成员变量 double mMinWidth; }; #endif // TRANSPARENTDRAGGABLERESUL_H