#include "formdraw.h" #include "ui_formdraw.h" #include "CallManage.h" #include #include "geometryutils.h" #include "ConsoleOutputWidget.h" #include "DraggablePixmap.h" #include "TransparentDraggableRect.h" //以下参数从配置文件读取 extern int g_iIndex; extern int g_iNum; extern int g_iOneWidth; //道宽 extern int g_iHeadHigh; //道头高度 extern int g_iTitleHigh; //道对象高度 extern int g_iCurveHigh;//曲线高度 extern int g_iMove; //道头偏移 extern int g_iPointNum; // number of points in graph extern int g_iLineNum; // number of Line extern int g_iWidth; //道宽 // extern int g_iX1; extern int g_iX2; extern int g_iY1; extern int g_iY2; extern int g_iCanZoom ; // extern double g_dPixelPerCm;//每厘米像素数 extern int g_iScale; extern void AppendConsole(Priority priority, const QString &output); //曲线绘制(多个) FormDraw::FormDraw(QWidget *parent, QString strWellName, QString strTrackName) : QWidget(parent), ui(new Ui::FormDraw) { ui->setupUi(this); setAcceptDrops(true); m_strWellName = strWellName; m_strTrackName = strTrackName; connect(CallManage::getInstance(), SIGNAL(sig_AddLine(QString, QString, QString, QString, QString)), this, SLOT(s_addLine(QString, QString, QString, QString, QString))); connect(CallManage::getInstance(), SIGNAL(sig_AddLine_Property(QString, QString, QString, QString, QString, double, double, QColor, double, Qt::PenStyle)), this, SLOT(s_AddLine_Property(QString, QString, QString, QString, QString, double, double, QColor, double, Qt::PenStyle))); connect(CallManage::getInstance(), SIGNAL(sig_delLine(QString, QString, QString, QString)), this, SLOT(s_delLine(QString, QString, QString, QString))); connect(CallManage::getInstance(), SIGNAL(sig_MouseMove(QString, QString, QString, float)), this, SLOT(s_MouseMove(QString, QString, QString, float))); } FormDraw::~FormDraw() { delete ui; } void FormDraw::paintEvent(QPaintEvent*) { // QPainter painter(this); // QRect rect = this->rect(); // //背景透明 // painter.fillRect(rect.left(), rect.top(), rect.width(), rect.height(), QColor(0, 0, 0, 0)); //QColor(67, 67, 67, 100) // painter.setPen(QPen(Qt::green,2,Qt::DashLine)); // //painter.setBrush(QBrush(Qt::red,Qt::SolidPattern)); //// QFont font1("微软雅黑", 10, false, false); //fontSize 10 //// painter.setFont(font1); //// painter.setPen(QColor(0, 0, 0)); // fontColor QColor(220, 220, 220) //// painter.drawText(rect.left() + 10, 10, QStringLiteral("画图")); // titleBarText QStringLiteral("动画") // QRect rectRound(rect.left()+2,rect.top()+4, rect.width()-3, rect.height()-4); // painter.drawRoundRect(rectRound); } void FormDraw::s_addLine(QString strUuid, QString strSlfName, QString strWellName, QString strTrackName, QString strLineName) { //井名&道名不一致 if(strUuid == m_strUuid && m_strWellName == strWellName && m_strTrackName == strTrackName) { } else { return; } AppendConsole(PAI_INFO, "FormDraw s_addLine"); if(m_listLineName.contains(strLineName)) { qDebug() << "FormDraw strLineName already exist! " << strLineName; return; } // QMyCustomPlot *curv = new QMyCustomPlot(this, strSlfName, strWellName, strTrackName, strLineName); curv->m_strUuid = m_strUuid; //背景设置成透明色 curv->setBackground(Qt::transparent); curv->setStyleSheet("background: transparent;"); // //QRect rect = this->rect(); //curv->setGeometry(rect.left(),rect.top(), rect.width(), rect.height()); double dHight = 0; dHight = (g_iY2-g_iY1)*100.0/(double)g_iScale * g_dPixelPerCm; qDebug() << "FormDraw dHight=" << QString::number((int)dHight-3184); if(dHight>32767) { dHight = 32767; } //curv->setMaximumHeight((int)dHight); //curv->setViewport(QRect(0, 0, g_iOneWidth, (int)dHight));//7500-3184 curv->setGeometry(0, 0, g_iOneWidth, (int)dHight);//7500-3184 //curv->resize(INT_MAX, INT_MAX); // 使用 INT_MAX 来避免16位整数的限制 // QSizePolicy policy(QSizePolicy::Expanding, QSizePolicy::Expanding); // curv->setSizePolicy(policy); initForm(curv, strSlfName, strLineName); curv->show(); // m_listLineName.push_back(strLineName); } void FormDraw::s_AddLine_Property(QString strUuid, QString strSlfName, QString strWellName, QString strTrackName, QString strLineName, double newLeftScale, double newRightScale, QColor lineColor, double width, Qt::PenStyle lineStyle) { //井名&道名不一致 if(strUuid == m_strUuid && m_strWellName == strWellName && m_strTrackName == strTrackName) { } else { return; } qDebug() << "FormDraw s_AddLine_Property"; AppendConsole(PAI_INFO, "FormDraw s_AddLine_Property"); if(m_listLineName.contains(strLineName)) { qDebug() << "FormDraw strLineName already exist! " << strLineName; return; } // QMyCustomPlot *curv = new QMyCustomPlot(this, strSlfName, strWellName, strTrackName, strLineName); curv->m_strUuid = m_strUuid; //背景设置成透明色 curv->setBackground(Qt::transparent); curv->setStyleSheet("background: transparent;"); // //QRect rect = this->rect(); //curv->setGeometry(rect.left(),rect.top(), rect.width(), rect.height()); double dHight = 0; dHight = (g_iY2-g_iY1)*100.0/(double)g_iScale * g_dPixelPerCm; qDebug() << "FormDraw dHight=" << QString::number((int)dHight-3184); if(dHight>32767) { dHight = 32767; } //curv->setMaximumHeight((int)dHight); //curv->setViewport(QRect(0, 0, g_iOneWidth, (int)dHight));//7500-3184 curv->setGeometry(0, 0, g_iOneWidth, (int)dHight);//7500-3184 //curv->resize(INT_MAX, INT_MAX); // 使用 INT_MAX 来避免16位整数的限制 // QSizePolicy policy(QSizePolicy::Expanding, QSizePolicy::Expanding); // curv->setSizePolicy(policy); AppendConsole(PAI_INFO, "FormDraw s_AddLine_Property 1"); curv->show(); AppendConsole(PAI_INFO, "FormDraw s_AddLine_Property 2"); initForm(curv, strSlfName, strLineName, newLeftScale, newRightScale, lineColor, width, lineStyle); // m_listLineName.push_back(strLineName); AppendConsole(PAI_INFO, "FormDraw s_AddLine_Property end"); } void FormDraw::s_delLine(QString strUuid, QString strWellName, QString strTrackName, QString strLineName) { //井名&道名不一致 if(strUuid == m_strUuid && m_strWellName == strWellName && m_strTrackName == strTrackName) { } else { return; } qDebug() << "FormDraw s_delLine"; if(m_listLineName.contains(strLineName)) { } else { qDebug() << "FormDraw strLineName not exist! " << strLineName; return; } // // 获取当前widget的所有子控件 const QObjectList &children = this->children(); // 遍历子控件列表 for (QObject *child : children) { // 判断子控件是否为QWidget类型 if (QWidget *childWidget = qobject_cast(child)) { // 打印子控件的信息,使用缩进表示层级关系 qDebug() << QString("%1").arg(childWidget->objectName()); QString strObjName = childWidget->objectName(); if(strObjName=="QMyCustomPlot") { QMyCustomPlot *form = (QMyCustomPlot*)childWidget; if(form->m_strLineName == strLineName) { childWidget->deleteLater(); // 安排控件的删除,稍后执行 m_listLineName.removeOne(strLineName); //break; } } } } } void FormDraw::s_MouseMove(QString strUuid, QString strWellName, QString strTrackName, float dep) { //井名&道名不一致 if(strUuid == m_strUuid && m_strWellName == strWellName && m_strTrackName == strTrackName) { } else { return; } qDebug() << "FormDraw s_MouseMove"; // QString sss=" depth:"+QString::number(dep); float fValue=-9999; // 获取当前widget的所有子控件 const QObjectList &children = this->children(); // 遍历子控件列表 for (QObject *child : children) { // 判断子控件是否为QWidget类型 if (QWidget *childWidget = qobject_cast(child)) { // 打印子控件的信息,使用缩进表示层级关系 qDebug() << QString("%1").arg(childWidget->objectName()); QString strObjName = childWidget->objectName(); if(strObjName=="QMyCustomPlot") { QMyCustomPlot *form = (QMyCustomPlot*)childWidget; // CLogIO *logio=new CLogIO(); logio->Open(form->m_strSlfName.toStdString().c_str(),CSlfIO::modeRead); int index=logio->OpenCurve(form->m_strLineName.toStdString().c_str()); if(index<0) { delete logio; return; } logio->ReadCurve(index, dep, 1, &fValue); logio->CloseCurve(index); delete logio; sss+=" " + form->m_strLineName + ":"+QString::number(fValue); } } } QStatusBar *pStatusbar = ::GetStatusBar(); if(pStatusbar) { pStatusbar->showMessage(sss); } } void FormDraw::s_handleRectRangeChange(QCPRange newRange) { } void FormDraw::setupLineStyleDemo(QMyCustomPlot *customPlot) { // customPlot->legend->setVisible(true); // customPlot->legend->setFont(QFont("Helvetica", 9)); // QPen pen; // QStringList lineNames; // lineNames << "lsNone" << "lsLine" << "lsStepLeft" << "lsStepRight" << "lsStepCenter" << "lsImpulse"; // for (int i = QCPGraph::lsNone; i <= QCPGraph::lsImpulse; ++i) // { // customPlot->addGraph(); // pen.setColor(QColor(qSin(i*1+1.2)*80+80, qSin(i*0.3+0)*80+80, qSin(i*0.3+1.5)*80+80)); // customPlot->graph()->setPen(pen); // 设置图表的画笔 // customPlot->graph()->setName(lineNames.at(i-QCPGraph::lsNone)); // customPlot->graph()->setLineStyle((QCPGraph::LineStyle)i); // 设置图表线段的风格 // customPlot->graph()->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, 5)); // 设置图表散点图的样式 // QVector x(15), y(15); // for (int j=0; j<15; ++j) // { // x[j] = j/15.0 * 5*3.14 + 0.01; // y[j] = 7*qSin(x[j])/x[j] - (i-QCPGraph::lsNone)*5 + (QCPGraph::lsImpulse)*5 + 2; // } // customPlot->graph()->setData(x, y); // customPlot->graph()->rescaleAxes(true); // } // // 放大一点 // customPlot->yAxis->scaleRange(1.1, customPlot->yAxis->range().center()); // customPlot->xAxis->scaleRange(1.1, customPlot->xAxis->range().center()); // customPlot->xAxis->setTicks(true); // customPlot->yAxis->setTicks(true); // customPlot->xAxis->setTickLabels(true); // customPlot->yAxis->setTickLabels(true); // customPlot->axisRect()->setupFullAxesBox(); } void FormDraw::setupSelectionDemo(QMyCustomPlot *customPlot) { //setupLineStyleDemo(customPlot); customPlot->setInteractions(QCP::iSelectAxes | QCP::iSelectLegend | QCP::iSelectPlottables | QCP::iMultiSelect); // 轴、图例、图表可以被选择,并且是多选的方式 customPlot->setSelectionRectMode(QCP::srmCustom); // 鼠标框选 //customPlot->setSelectionRectMode(QCP::srmSelect); // 鼠标框选 // customPlot->setMultiSelectModifier(Qt::ControlModifier); // 使用ctrl键来多选 // customPlot->xAxis->setSelectableParts(QCPAxis::spAxis | QCPAxis::spAxisLabel | QCPAxis::spTickLabels); // 轴的三个部分都可以被选择 // customPlot->yAxis->setSelectableParts(QCPAxis::spAxis | QCPAxis::spAxisLabel | QCPAxis::spTickLabels); // customPlot->xAxis->setLabel("xAxis"); // customPlot->yAxis->setLabel("yAxis"); // customPlot->legend->setSelectableParts(QCPLegend::spItems); // 图例本身不能被选择,只有里面的项可以被选择 // customPlot->legend->setSelectedIconBorderPen(Qt::NoPen); // 设置图例里的项被选择时不显示Icon的边框 //选框黑色虚线 //customPlot->selectionRect()->setPen(QPen(Qt::black,1,Qt::DashLine)); //customPlot->selectionRect()->setBrush(QBrush(QColor(0,0,100,50))); // // QPen pen(Qt::NoPen); // 使用无画笔,这样就不会有边框了 // QBrush brush(Qt::transparent); // 使用透明刷子,这样就不会有填充颜色了 // customPlot->selectionRect()->setPen(pen); // 设置选择区域的画笔为无画笔 // customPlot->selectionRect()->setBrush(brush); // 设置选择区域的刷子为透明刷子 for (int i=0; i < customPlot->graphCount(); ++i) { QCPGraph *graph = customPlot->graph(i); graph->setSelectable(QCP::stDataRange); } //connect(customPlot->selectionRect(), SIGNAL(accepted(QRect, QMouseEvent*)), this, SLOT(s_selectionRectAccepted(QRect, QMouseEvent*))); connect(customPlot->selectionRect(), &QCPSelectionRect::accepted, [customPlot](){ if(customPlot->m_bDrawRect == false) { customPlot->m_bDrawRect = true; return; } // 当选择完成时,获取矩形范围并放大 QRectF rect = customPlot->selectionRect()->rect(); // 获取选择的矩形区域(像素坐标) // 转换为坐标轴范围 double top = rect.top(); double bottom = rect.bottom(); double right_Hight = customPlot->xAxis->pixelToCoord(top); double left_Low = customPlot->xAxis->pixelToCoord(bottom); if(right_Hight-left_Low>5) { //添加图形 //emit CallManage::getInstance()->sig_addImageToPlot(customPlot, left_Low, right_Hight, ":/image/file.png"); customPlot->addImageToPlot(left_Low, right_Hight, ":/image/file.png"); } }); // 连接QCustomPlot的信号,selectionChangedByUser表明是由鼠标点击进行的选择 // 这里主要就是同步图表和图例的显示 connect(customPlot, &QMyCustomPlot::selectionChangedByUser, [customPlot](){ for (int i=0; i < customPlot->graphCount(); ++i) { QCPGraph *graph = customPlot->graph(i); QCPPlottableLegendItem *item = customPlot->legend->itemWithPlottable(graph); if (item->selected() && !graph->selected()) { graph->setSelection(QCPDataSelection(graph->data()->dataRange())); // 当图例项被选择时,选择图表全部的数据 } else if (graph->selected()) { item->setSelected(true); QCPDataSelection selection = customPlot->graph(i)->selection(); // 遍历选中的数据范围 for (int j = 0; j < selection.dataRangeCount(); ++j) { QCPDataRange dataRange = selection.dataRange(j); double left_Low = customPlot->graph(i)->data()->at(dataRange.begin())->key; double right_Hight = customPlot->graph(i)->data()->at(dataRange.end())->key; if(right_Hight-left_Low>1) { //添加图形 //emit CallManage::getInstance()->sig_addImageToPlot(customPlot, left_Low, right_Hight, ":/image/file.png"); customPlot->addImageToPlot(left_Low, right_Hight, ":/image/file.png"); } } /*QCPDataSelection selection = customPlot->graph(i)->selection(); // 遍历选中的数据范围 for (int j = 0; j < selection.dataRangeCount(); ++j) { QCPDataRange dataRange = selection.dataRange(j); // 遍历选中范围内的数据点 for (int k = dataRange.begin(); k < dataRange.end(); ++k) { double key = customPlot->graph(i)->data()->at(k)->key; double value = customPlot->graph(i)->data()->at(k)->value; AppendConsole(PAI_INFO, QString("曲线 %1: (%2, %3)").arg(i).arg(key).arg(value)); } }*/ } } }); } void FormDraw::s_selectionRectAccepted(const QRect &rect, QMouseEvent *event) { // 转换为坐标轴范围 // double x1 = widget->xAxis->pixelToCoord(rect.left()); // double x2 = widget->xAxis->pixelToCoord(rect.right()); // double y1 = widget->yAxis->pixelToCoord(rect.top()); // double y2 = widget->yAxis->pixelToCoord(rect.bottom()); } void FormDraw::initForm(QMyCustomPlot *widget, QString strSlfName, QString strLineName, double newLeftScale, double newRightScale, QColor lineColor, double width, Qt::PenStyle lineStyle) { AppendConsole(PAI_INFO, "FormDraw initForm"); CLogIO *logio=new CLogIO(); logio->Open(strSlfName.toStdString().c_str(),CSlfIO::modeRead); int index=logio->OpenCurve(strLineName.toStdString().c_str()); if(index<0) { delete logio; return; } Slf_CURVE curveinfo; float *val; DWORD count; float sdep,edep,rlev; float vmax,vmin; // logio->GetCurveInfo(index,&curveinfo); sdep=curveinfo.StartDepth; edep=curveinfo.EndDepth; rlev=curveinfo.DepLevel; // count=(curveinfo.EndDepth-curveinfo.StartDepth)/curveinfo.DepLevel+1.5; val=new float[count]; logio->ReadCurve(index,curveinfo.StartDepth,count,&val[0]); logio->CloseCurve(index); delete logio; //最大值,最小值 vmax=vmin=val[0]; // for(int i=1;ival[i])vmin=val[i]; // } //slf文件读取曲线 QVector x, y; for(int i=0; ival[i])vmin=val[i]; } // x.append(-(sdep+ rlev*i)); y.append(val[i]); } if(newLeftScale!=-9999) { vmax = newRightScale; vmin = newLeftScale; } //赋值 m_vmax = vmax; m_vmin = vmin; AppendConsole(PAI_INFO, "FormDraw initForm ReadCurve end"); widget->setInteractions(QCP::iSelectLegend | QCP::iSelectPlottables); //框选----- // widget->setInteraction(QCP::iRangeDrag, false); // 关闭拖动 // widget->setSelectionRectMode(QCP::SelectionRectMode::srmSelect); // 启用框选放大 // // // widget->selectionRect()->setPen(QPen(Qt::black, 1, Qt::DashLine)); // 虚线边框 // widget->selectionRect()->setBrush(QBrush(QColor(0,0,100,50))); // 半透明蓝色填充 // // // QCPSelectionRect *selectionRect = new QCPSelectionRect(widget); // connect(selectionRect, &QCPSelectionRect::accepted, [=]() { // // 当选择完成时,获取矩形范围并放大 // QRectF rect = selectionRect->rect(); // 获取选择的矩形区域(像素坐标) // // 转换为坐标轴范围 // double x1 = widget->xAxis->pixelToCoord(rect.left()); // double x2 = widget->xAxis->pixelToCoord(rect.right()); // double y1 = widget->yAxis->pixelToCoord(rect.top()); // double y2 = widget->yAxis->pixelToCoord(rect.bottom()); // }); widget->m_iX1 = vmin; widget->m_iX2 = vmax; widget->m_iY1 = g_iY1; widget->m_iY2 = g_iY2; // widget->xAxis->setRange(vmin, vmax); widget->yAxis->setRange(g_iY1, g_iY2); widget->axisRect()->setupFullAxesBox(); // widget->xAxis->ticker()->setTickCount(10);//x个主刻度 widget->yAxis->ticker()->setTickCount(60);//y个主刻度 //对调XY轴,在最前面设置 QCPAxis *yAxis = widget->yAxis; QCPAxis *xAxis = widget->xAxis; widget->xAxis = yAxis; widget->yAxis = xAxis; // // // widget->yAxis->setRange(vmin, vmax); // widget->xAxis->setRange(g_iY1, g_iY2); // widget->axisRect()->setupFullAxesBox(); // // // widget->yAxis->ticker()->setTickCount(10);//x个主刻度 // widget->xAxis->ticker()->setTickCount(60);//y个主刻度 // //slf文件读取曲线 // QVector x, y; // for(int i=0; irescaleAxes(); //widget->replot();//屏蔽,缩减时间 AppendConsole(PAI_INFO, "FormDraw initForm end"); } void FormDraw::addRandomGraph(QMyCustomPlot *widget, QVector x, QVector y, QString strSlfName, QString strLineName, double newLeftScale, double newRightScale, QColor newlineColor, double width, Qt::PenStyle lineStyle) { AppendConsole(PAI_INFO, "FormDraw addRandomGraph"); widget->addGraph(); if(strLineName=="") { strLineName = QString("曲线 %1").arg(widget->graphCount()); } widget->graph()->setName(strLineName); widget->graph()->setData(x, y); if(newLeftScale!=-9999) { widget->graph()->setLineStyle((QCPGraph::LineStyle)(lineStyle));//曲线 widget->graph()->setScatterStyle(QCPScatterStyle((QCPScatterStyle::ScatterShape)(1))); QPen graphPen; graphPen.setColor(newlineColor); graphPen.setWidthF(width); graphPen.setStyle(lineStyle);//实线 widget->graph()->setPen(graphPen); } else { widget->graph()->setLineStyle((QCPGraph::LineStyle)(1));//曲线 //widget->graph()->setLineStyle((QCPGraph::LineStyle)(std::rand()%5+1)); //widget->graph()->setLineStyle((QCPGraph::LineStyle)(QCPGraph::lsLine));//曲线 //widget->graph()->setLineStyle((QCPGraph::LineStyle)(QCPGraph::lsImpulse));//杆状 // if (std::rand()%100 > 50) // widget->graph()->setScatterStyle(QCPScatterStyle((QCPScatterStyle::ScatterShape)(std::rand()%14+1))); widget->graph()->setScatterStyle(QCPScatterStyle((QCPScatterStyle::ScatterShape)(1))); // widget->graph()->setScatterStyle(QCPScatterStyle(QPixmap(":/image/file.png"))); //widget->graph()->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssDisc, 5)); QPen graphPen; newlineColor = QColor(std::rand()%245+10, std::rand()%245+10, std::rand()%245+10); graphPen.setColor(newlineColor); //graphPen.setWidthF(std::rand()/(double)RAND_MAX*2+1); width = 2; graphPen.setWidthF(width); graphPen.setStyle(Qt::SolidLine);//实线 widget->graph()->setPen(graphPen); //widget->replot(); } //道-对象 m_formTrack->Add(strSlfName, m_strWellName, m_strTrackName, strLineName, newlineColor, width, m_vmax, m_vmin); AppendConsole(PAI_INFO, "FormDraw addRandomGraph end"); } void FormDraw::dragEnterEvent(QDragEnterEvent* event) { qDebug() << "FormDraw dragEnterEvent"; const QMimeData* mimeData = event->mimeData(); // 检查拖拽的数据类型,确定是否接受拖拽 if (event->mimeData()->hasFormat("text/plain")) { event->acceptProposedAction(); //QApplication::setOverrideCursor(Qt::PointingHandCursor); // 设置鼠标为可添加状态 } else { event->ignore(); QApplication::setOverrideCursor(Qt::ForbiddenCursor); // 设置鼠标为不可添加状态 } } void FormDraw::dragMoveEvent(QDragMoveEvent* event) { qDebug() << "FormDraw dragMoveEvent"; // 可以在这里更新鼠标的位置,根据位置判断是否可以放置 // ... //dragEnterEvent(event); // 可以使用相同的逻辑 //event->accept(); } void FormDraw::dropEvent(QDropEvent* event) { qDebug() << "FormDraw dropEvent"; // 处理放置动作,更新UI或数据 if (event->mimeData()->hasFormat("text/plain")) { // 获取拖拽的数据 QString strExtern = event->mimeData()->text(); qDebug() << strExtern; // QStringList list = strExtern.split("#@@#");//QString字符串分割函数 if (list.size() > 2) { QString strSlfName = list[0]; QString strWellName = list[1]; QString strLineName = list[2]; qDebug() << "strSlfName:" << strSlfName<< " strWellName:" << strWellName<< " strLineName:" << strLineName; if(m_strWellName == strWellName) { //新建曲线 emit CallManage::getInstance()->sig_AddLine(m_strUuid, strSlfName, strWellName, m_strTrackName, strLineName); // 接受拖拽事件 event->setDropAction(Qt::MoveAction); event->accept(); } else { // 如果井名不正确,不接受拖拽事件 event->ignore(); } } else { // 如果数据格式不正确,不接受拖拽事件 event->ignore(); } } else { // 如果数据格式不正确,不接受拖拽事件 event->ignore(); } // 恢复鼠标光标 //QApplication::restoreOverrideCursor(); }