#include "stdafx.h" #include "ImageShowDialogClass.h" #include "ui_ImageShowDialogClass.h" ImageShowDialogClass ::ImageShowDialogClass(QWidget *parent) : QDialog(parent) { ui=new Ui::ImageShowDialogClass; ui->setupUi(this); ui->m_plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); connect(this->ui->m_plot, SIGNAL(mouseMove(QMouseEvent*)), this, SLOT(updateCursor(QMouseEvent*))); this->graphclass=LAMPDATASHOWCLASS::NOWINDOWS; this->menubar = new QMenuBar(this); QMenu* windowsMenu = this->menubar->addMenu(u8"数据"); QAction* action_cursor_enable = windowsMenu->addAction(u8"打开游标"); QObject::connect(action_cursor_enable,SIGNAL(triggered()),this,SLOT(on_action_cursor_enable_trigged())); this->tracer=new QCPItemTracer(this->ui->m_plot); this->m_plot = ui->m_plot; this->desCursor = nullptr; this->HlineCursor = nullptr; this->VlineCursor = nullptr; this->desCursorflag=false; this->HlineCursorflag=false; this->VlineCursorflag = false; this->statusbar=new QStatusBar(this); this->statusbar->setMaximumHeight(20); this->statusbar->setMinimumHeight(20); ui->verticalLayout->setMenuBar(this->menubar); ui->verticalLayout->addWidget(this->statusbar); this->setLayout(ui->verticalLayout); } ImageShowDialogClass::~ImageShowDialogClass() {} void ImageShowDialogClass::on_action_cursor_enable_trigged() { this->desCursor = new ImageShowCursorDesClass(this); this->desCursorflag = true; for (size_t i = 0; i < this->getGraphCount(); i++) { if (this->getGraphClass(i) == LAMPDATASHOWCLASS::LAMPColorMap) { this->HlineCursorflag = true; this->VlineCursorflag = true; } } //下面的代码就是设置游标的外观 this->setMouseTracking(true); tracer->setInterpolating(false);//禁用插值 tracer->setPen(QPen(Qt::DashLine));//虚线游标 tracer->setStyle(QCPItemTracer::tsPlus);//游标样式:十字星、圆圈、方框 tracer->setBrush(Qt::red);//游标颜色 if (this->graphclass == LAMPDATASHOWCLASS::LAMPColorMap) { this->HlineCursor = new ImageShowCursorLineClass(this); this->VlineCursor = new ImageShowCursorLineClass(this); QObject::connect(this->HlineCursor, SIGNAL(windowsClose()), this, SLOT(on_action_Hlinecursor_close_trigged())); QObject::connect(this->VlineCursor, SIGNAL(windowsClose()), this, SLOT(on_action_VVlinecursor_close_trigged())); QObject::connect(this->ui->m_plot->xAxis, SIGNAL(rangeChanged(QCPRange)), this->HlineCursor, SLOT(xAxisRangeChanged(QCPRange))); QObject::connect(this->ui->m_plot->yAxis, SIGNAL(rangeChanged(QCPRange)), this->HlineCursor, SLOT(xAxisRangeChanged(QCPRange))); this->HlineCursor->show(); this->VlineCursor->show(); } this->desCursor->show(); QObject::connect(this->desCursor, SIGNAL(windowsClose()), this, SLOT(on_action_descursor_close_trigged())); } void ImageShowDialogClass::PlotLine(QVector xs, QVector dataValues,QString Name) { if (dataValues.count() == 0) { return; } QCPGraph* graph = ui->m_plot->addGraph(); graph->setName(Name); graph->setData(xs, dataValues); double min_y = dataValues[0]; double max_y = dataValues[0]; for (size_t i = 0; i < dataValues.count(); i++) { min_y = min_y > dataValues[i] ? dataValues[i] : min_y; max_y = max_y < dataValues[i] ? dataValues[i] : max_y; } double min_x = xs[0]; double max_x = xs[0]; for (size_t i = 0; i < xs.count(); i++) { min_x = min_x > xs[i] ? xs[i] : min_x; max_x = max_x < xs[i] ? xs[i] : max_x; } ui->m_plot->xAxis->setRange(min_x, max_x); ui->m_plot->yAxis->setRange(min_y, max_y); ui->m_plot->legend->setVisible(true); ui->m_plot->replot(); //下面的代码就是设置游标的外观 this->setMouseTracking(true); tracer->setInterpolating(false);//禁用插值 tracer->setPen(QPen(Qt::DashLine));//虚线游标 tracer->setStyle(QCPItemTracer::tsPlus);//游标样式:十字星、圆圈、方框 tracer->setBrush(Qt::red);//游标颜色 tracer->setGraph(graph); // 确保游标跟随 this->m_graphMap.insert(Name, graph); } void ImageShowDialogClass::Scatter(double dx,double dy) { QVectorxs(0); QVectorys(0); xs.push_back(dx); ys.push_back(dy); // 设置画笔风格 QPen drawPen; drawPen.setColor(Qt::red); drawPen.setWidth(4); // 绘制散点 QCPGraph* curGraph = ui->m_plot->addGraph(); curGraph->setPen(drawPen); curGraph->setLineStyle(QCPGraph::lsNone); curGraph->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, 2)); curGraph->setData(xs, ys); ui->m_plot->xAxis->setVisible(true); ui->m_plot->yAxis->setVisible(true); } void ImageShowDialogClass::Scatter(QVector xs, QVector ys) { // 设置画笔风格 QPen drawPen; drawPen.setColor(Qt::red); drawPen.setWidth(4); // 绘制散点 QCPGraph* curGraph = ui->m_plot->addGraph(); curGraph->setPen(drawPen); curGraph->setLineStyle(QCPGraph::lsNone); curGraph->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, 2)); curGraph->setData(xs, ys); ui->m_plot->xAxis->setVisible(true); ui->m_plot->yAxis->setVisible(true); } void ImageShowDialogClass::load_double_MatrixX_data(Eigen::MatrixXd data, QString name) { this->setWindowTitle(name); this->graphclass = LAMPDATASHOWCLASS::LAMPColorMap; int ny = data.rows(); // 行数 int nx = data.cols(); // 列数 // 创建 Color Map QCPColorMap* colorMap = new QCPColorMap(ui->m_plot->xAxis, ui->m_plot->yAxis); colorMap->data()->setSize(nx, ny); // 设置 Color Map 的大小 colorMap->data()->setRange(QCPRange(0, nx), QCPRange(0, ny)); // 设置坐标轴的范围 // 填充数据 for (int xIndex = 0; xIndex < nx; ++xIndex) { for (int yIndex = 0; yIndex < ny; ++yIndex) { double magnitude = data(yIndex, xIndex); // 或者使用 std::arg() 获取相位 colorMap->data()->setCell(xIndex, yIndex,magnitude); } } colorMap->setGradient(QCPColorGradient::gpJet); colorMap->rescaleDataRange(true); ui->m_plot->rescaleAxes(); ui->m_plot->replot(); } void ImageShowDialogClass::load_double_MatrixX_data(Eigen::MatrixXd X, Eigen::MatrixXd Y, Eigen::MatrixXd data, QString name) { this->graphclass = LAMPDATASHOWCLASS::LAMPColorMap; int nx = data.cols(); // 行数 int ny = data.rows(); // 列数 // 创建 Color Map ui->m_plot->xAxis->setRange(X(0, 0), X(0, nx - 1)); ui->m_plot->yAxis->setRange(Y(0, 0), Y(ny - 1, 0)); QCPColorMap* colorMap = new QCPColorMap(ui->m_plot->xAxis, ui->m_plot->yAxis); colorMap->data()->setSize(ny, nx); // 设置 Color Map 的大小 colorMap->data()->setRange(QCPRange(X(0,0), X(0,nx-1)), QCPRange(Y(0,0),Y(ny-1,0))); // 设置坐标轴的范围 // 填充数据 for (int xIndex = 0; xIndex < nx; ++xIndex) { for (int yIndex = 0; yIndex < ny; ++yIndex) { double magnitude = data(yIndex, xIndex); // 或者使用 std::arg() 获取相位 colorMap->data()->setCell(yIndex, xIndex, magnitude); } } // add a color scale: QCPColorScale* m_colorScale = new QCPColorScale(m_plot); m_plot->plotLayout()->addElement(0, 1, m_colorScale); m_colorScale->setType(QCPAxis::atRight); colorMap->setColorScale(m_colorScale); colorMap->setGradient(QCPColorGradient::gpJet); colorMap->rescaleDataRange(true); ui->m_plot->rescaleAxes(); ui->m_plot->replot(); } void ImageShowDialogClass::remove_Data(QString name) { for(size_t i=0;im_plot->graphCount();i++){ if (this->m_plot->graph(i)->name() == name) { this->m_plot->removeGraph(i); this->m_plot->replot(); return; } } } LAMPDATASHOWCLASS ImageShowDialogClass::getGraphClass(size_t i) { if (this->m_plot->graphCount() == 0 || i > this->m_plot->graphCount()) { return LAMPDATASHOWCLASS::NOWINDOWS; } QCPAbstractPlottable* plottable = this->ui->m_plot->plottable(i); if (dynamic_cast(plottable)) { return LAMPDATASHOWCLASS::LAMPGraph; } else if (dynamic_cast(plottable)) { return LAMPDATASHOWCLASS::LAMPScatterStyle; } else if (dynamic_cast(plottable)) { return LAMPDATASHOWCLASS::LAMPColorMap; } else { return LAMPDATASHOWCLASS::NOWINDOWS; } } size_t ImageShowDialogClass::getGraphCount() { return this->m_plot->graphCount(); } void ImageShowDialogClass::on_action_descursor_close_trigged() { this->desCursorflag = false; } void ImageShowDialogClass::on_action_Hlinecursor_close_trigged() { this->HlineCursorflag = false; } void ImageShowDialogClass::on_action_VVlinecursor_close_trigged() { this->VlineCursorflag = false; } void ImageShowDialogClass::updateCursor(QMouseEvent *event) { if (this->desCursorflag &&this->HlineCursorflag &&this->VlineCursorflag) { //下面的代码就是设置游标的外观 this->setMouseTracking(false); } else { // 准备获取数据 QPoint pos = event->pos(); double x=this->m_plot->xAxis->pixelToCoord(pos.x()); // 将鼠标位置映射到图表坐标系中 double y = this->m_plot->yAxis->pixelToCoord(pos.y()); this->statusbar->showMessage(u8"X: "+QString::number(x,'f', 6)+" y: "+QString::number(y, 'f', 6)); if (this->desCursorflag) { if (this->graphclass == LAMPDATASHOWCLASS::LAMPColorMap) { QCPColorMap* colorMap = dynamic_cast(this->ui->m_plot->plottable(0)); double dataValue = colorMap->data()->data(x, y); this->desCursor->updateCursorContent(u8"X: " + QString::number(x, 'f', 6) + " y: " + QString::number(y, 'f', 6) +u8"\n" +u8"DataValue: "+QString::number(dataValue)); double xMin = this->m_plot->xAxis->range().lower; double xMax = this->m_plot->xAxis->range().upper; double yMin = this->m_plot->yAxis->range().lower; double yMax = this->m_plot->yAxis->range().upper; long XCount = 1000; double xdelte = (xMax - xMin) / (XCount-1); double ydelte = (yMax - yMin) / (XCount-1); qDebug() << xMin << "," << xMax << " " << yMin << "," << yMax << " " << XCount<<" "< Hx(XCount); QVector Hy(XCount); QVector Vx(XCount); QVector Vy(XCount); for (long i = 0; i < XCount; i++) { Hx[i] = i * xdelte + xMin; Hy[i] = colorMap->data()->data(Hx[i], y); Vx[i] = i * ydelte + yMin; Vy[i] = colorMap->data()->data(x, Vx[i]); } this->HlineCursor->UpdatePlotLine(Hx, Hy, u8"水平"); // 水平 this->VlineCursor->UpdatePlotLine(Vx, Vy, u8"垂直"); // 垂直 } else if (this->graphclass == LAMPDATASHOWCLASS::LAMPGraph) { } else if (this->graphclass == LAMPDATASHOWCLASS::LAMPScatterStyle) { } else { this->desCursor->updateCursorContent(u8"无法识别图像类型"); } } if (this->HlineCursorflag) { } if (this->VlineCursorflag) { } } } ImageShowCursorDesClass::ImageShowCursorDesClass(QWidget* parent) { // 创建 QLabel label = new QLabel(this); QFont font; font.setPointSize(20); // 设置字体大小为20 label->setFont(font); // 创建布局 QVBoxLayout* layout = new QVBoxLayout(this); layout->addWidget(label); // 设置布局 setLayout(layout); this->resize(100, 50); } ImageShowCursorDesClass::~ImageShowCursorDesClass() { } void ImageShowCursorDesClass::closeEvent(QCloseEvent* event) { QDialog::closeEvent(event); } void ImageShowCursorDesClass::updateCursorContent(QString content) { this->label->setText(content); } ImageShowCursorLineClass::ImageShowCursorLineClass(QWidget* parent):QDialog(parent) { this->menubar = new QMenuBar(this); //QMenu* toolMenu = this->menubar->addMenu(u8"工具"); //QAction* action_add_compare_line = toolMenu->addAction(u8"添加对比数据"); //QObject::connect(action_add_compare_line, SIGNAL(triggered()), this, SLOT(load_new_compare_line())); this->tracerEnable = false; this->tracer = nullptr; this->tracerXText = nullptr; this->tracerYText = nullptr; // 创建 QLabel this->customPlot = new QCustomPlot(this); // 创建布局 QVBoxLayout* layout = new QVBoxLayout(this); layout->addWidget(this->customPlot); // 设置布局 setLayout(layout); this->tracer = new QCPItemTracer(this->customPlot); this->tracerYText = new QCPItemText(this->customPlot); this->tracerXText = new QCPItemText(this->customPlot); QObject::connect(this->customPlot, SIGNAL(mouseMove(QMouseEvent*)), this, SLOT(updateCursor(QMouseEvent*))); this->customPlot->legend->setVisible(true); this->setMinimumWidth(600); this->setMinimumHeight(400); } ImageShowCursorLineClass::~ImageShowCursorLineClass() { } void ImageShowCursorLineClass::loadPlotLine(QVector xs, QVector dataValues,QString Name) { if (dataValues.count() == 0) { return; } QCPGraph* graph = this->customPlot->addGraph(); graph->setName(Name); graph->setData(xs, dataValues); double min_y = dataValues[0]; double max_y = dataValues[0]; for (size_t i = 0; i < dataValues.count(); i++) { min_y = min_y > dataValues[i] ? dataValues[i] : min_y; max_y = max_y < dataValues[i] ? dataValues[i] : max_y; } double min_x = xs[0]; double max_x = xs[0]; for (size_t i = 0; i < xs.count(); i++) { min_x = min_x > xs[i] ? xs[i] : min_x; max_x = max_x < xs[i] ? xs[i] : max_x; } customPlot->xAxis->setRange(min_x, max_x); customPlot->yAxis->setRange(min_y, max_y); customPlot->legend->setVisible(true); customPlot->replot(); //下面的代码就是设置游标的外观 this->setMouseTracking(true); tracer->setInterpolating(false);//禁用插值 tracer->setPen(QPen(Qt::DashLine));//虚线游标 tracer->setStyle(QCPItemTracer::tsPlus);//游标样式:十字星、圆圈、方框 tracer->setBrush(Qt::red);//游标颜色 tracer->setGraph(graph); // 确保游标跟随 this->m_graphMap.insert(Name, graph); this->TrackName = Name; } void ImageShowCursorLineClass::UpdatePlotLine(QVector xs, QVector dataValues, QString Name) { this->customPlot->clearGraphs(); this->loadPlotLine(xs, dataValues, Name); } void ImageShowCursorLineClass::updateCursor(QMouseEvent* event) { if (tracerEnable)//游标使能 { double x = this->customPlot->xAxis->pixelToCoord(event->pos().x());//鼠标点的像素坐标转plot坐标 tracer->setGraphKey(x);//设置游标的X值(这就是游标随动的关键代码) double traceX = tracer->position->key(); double traceY = tracer->position->value(); tracerXText->setText(QDateTime::fromMSecsSinceEpoch(traceX * 1000.0).toString("hh:mm:ss.zzz"));//游标文本框,指示游标的X值 tracerYText->setText(QString::number(traceY));//游标文本框,指示游标的Y值 ////计算游标X值对应的所有曲线的Y值 //for (int i = 0; i < this->customPlot->graphCount(); i++) //{ // QCPGraph* graph = dynamic_cast(this->customPlot->plottable(i)); // //搜索左边离traceX最近的key对应的点,详情参考findBegin函数的帮助 // QCPDataContainer::const_iterator coorPoint = graph->data().data()->findBegin(traceX, true);//true代表向左搜索 // qDebug() << QString("graph%1对应的Y值是").arg(i) << coorPoint->value; //} } } void ImageShowCursorLineClass::closeEvent(QCloseEvent* event) { QDialog::closeEvent(event); } void ImageShowCursorLineClass::xAxisRangeChanged(QCPRange range) { this->customPlot->xAxis->setRange(range); customPlot->replot(); } void ImageShowCursorLineClass::yAxisRangeChanged(QCPRange range) { this->customPlot->yAxis->setRange(range); customPlot->replot(); } void ImageShowCursorLineClass::on_SwichTracerGraph_Name() { } void ImageShowCursorLineClass::load_new_compare_line() { }