#include "QmlCustomPlot.h" #include #include QmlCustomPlot::QmlCustomPlot(QQuickItem* parent) : QQuickPaintedItem(parent) , m_timerId(0) { setFlag(QQuickItem::ItemHasContents, true); setAcceptedMouseButtons(Qt::AllButtons); connect(this, &QQuickPaintedItem::widthChanged, this, &QmlCustomPlot::updateCustomPlotSize); connect(this, &QQuickPaintedItem::heightChanged, this, &QmlCustomPlot::updateCustomPlotSize); auto t = new QTimer(this); t->setInterval(1000); t->setTimerType(Qt::VeryCoarseTimer); t->setSingleShot(false); connect(t, &QTimer::timeout, this, [&](){ setFps(m_fpsCounter); m_fpsCounter = 0; }); t->start(); } QmlCustomPlot::~QmlCustomPlot() { delete m_plot; m_plot = nullptr; if(m_timerId != 0) { killTimer(m_timerId); } } void QmlCustomPlot::initCustomPlot() { setPlot(new QCustomPlot()); } void QmlCustomPlot::setPlot(QCustomPlot *plot) { // m_plot = new QCustomPlot(); m_plot = plot; m_plot->setBackgroundScaled(true); m_plot->setBackgroundScaledMode(Qt::KeepAspectRatio); updateCustomPlotSize(); m_plot->xAxis->setLabel("x"); m_plot->yAxis->setLabel("y"); m_plot->xAxis->setRange(-50, 50); m_plot->yAxis->setRange(0, 100); m_plot ->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables | QCP::iSelectItems | QCP::iSelectOther); if(m_profileGraph == nullptr) { m_profileGraph = m_plot->addGraph(); m_profileGraph->setLineStyle(QCPGraph::lsNone); m_profileGraph->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssDisc, 2)); m_profileGraph->setPen(QPen(QColor(Qt::red))); } startTimer(1000 / 24); connect(m_plot, &QCustomPlot::afterReplot, this, &QmlCustomPlot::onCustomReplot); m_plot->replot(); } void QmlCustomPlot::setPoints(const QVector points) { QVector x; //(qsizetype(points.count())); QVector y; //(qsizetype(points.count())); for(const auto & p : points) { // break; if(qFuzzyIsNull(p.x()) && qFuzzyIsNull(p.y())) { qt_noop(); } x << p.x(); y << p.y(); } m_profileGraph->setData(x, y); // setLines({ // QLineF(rand() % 100 - 50, rand() % 100, rand() % 100 - 50, rand() % 100), // QLineF(rand() % 100 - 50, rand() % 100, rand() % 100 - 50, rand() % 100) // }); } void QmlCustomPlot::setLines(const QVector lines) { while(m_lineItems.count() > lines.count()) { m_plot->removeItem(m_lineItems.takeLast()); } m_lineItems.reserve(lines.count()); const QCPLineEnding lineEnding(QCPLineEnding::esNone); for(int i = 0; i < lines.count(); i++) { // const QPen linePen(QColor(Qt::green), 4); // const QColor color(Qt::green); // QRgb green = QRandomGenerator::generate(); // QRgb blue = QRandomGenerator::generate(); const QColor color { QRgb { QRandomGenerator::global()->generate() } }; const QPen linePen(color, 4); QCPItemLine * l; if(i >= m_lineItems.count()) { l = new QCPItemLine(m_plot); l->setPen(linePen); l->setHead(lineEnding); l->setTail(lineEnding); m_lineItems << l; } else { l = m_lineItems[i]; } const QPointF offset(0, 2); const auto & lineToSet = lines.at(i); l->start->setCoords(lineToSet.p1() + offset); l->end->setCoords(lineToSet.p2() + offset); } } void QmlCustomPlot::setContours(const QVector contours) { qDebug() << "contours count" << contours.count(); while(m_contourGraphs.count() > contours.count()) { m_plot->removeGraph(m_contourGraphs.takeLast()); } m_contourGraphs.reserve(contours.count()); for(int i = 0; i < contours.count(); i++) { const QColor color(rand() % 0xff, rand() % 0xff, rand() % 0xff); const QPen contourPen(color, 4); QCPGraph * c; // create new if(i >= m_contourGraphs.count()) { c = m_plot->addGraph(); c->setLineStyle(QCPGraph::lsNone); c->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssDisc, 2)); c->setPen(contourPen); m_contourGraphs << c; } // use existing graph object else { c = m_contourGraphs[i]; } // set data const auto & contourToAdd = contours.at(i); QVector x; //(qsizetype(contourToAdd.count())); QVector y; //(qsizetype(contourToAdd.count())); for(const auto & p : contourToAdd) { x << p.x(); y << p.y() + 5; } c->setData(x, y); } } void QmlCustomPlot::setFps(int fps) { m_fps = fps; emit fpsChanged(); } //void QmlCustomPlot::setPlot(QCustomPlot *plot) //{ //} void QmlCustomPlot::paint(QPainter* painter) { if(m_plot) { QPixmap picture(boundingRect().size().toSize()); QCPPainter qcpPainter(&picture); m_plot->toPainter(&qcpPainter); // m_bg->topLeft->setCoords(m_plot->xAxis->range().minRange, m_plot->yAxis->range().minRange); // m_bg->bottomRight->setCoords(m_plot->xAxis->range().maxRange, m_plot->yAxis->range().maxRange); // m_bg->topLeft->setCoords(0, 0); // m_bg->bottomRight->setCoords(640, 480); painter->drawPixmap(QPoint(), picture); // qDebug() << m_plot->axisRect(); } } QCustomPlot *QmlCustomPlot::plot() const { return m_plot; } int QmlCustomPlot::fps() const { return m_fps; } void QmlCustomPlot::mousePressEvent(QMouseEvent* event) { routeMouseEvents(event); } void QmlCustomPlot::mouseReleaseEvent(QMouseEvent* event) { routeMouseEvents(event); } void QmlCustomPlot::mouseMoveEvent(QMouseEvent* event) { routeMouseEvents(event); } void QmlCustomPlot::mouseDoubleClickEvent(QMouseEvent* event) { qDebug() << Q_FUNC_INFO; routeMouseEvents(event); } void QmlCustomPlot::wheelEvent(QWheelEvent *event) { routeWheelEvents(event); } void QmlCustomPlot::timerEvent(QTimerEvent *event) { // static double t, U; // U = ((double)rand() / RAND_MAX) * 5; // m_plot->graph(0)->addData(t, U); // qDebug() << Q_FUNC_INFO << QString("Adding dot t = %1, S = %2").arg(t).arg(U); // t++; m_plot->replot(); } void QmlCustomPlot::graphClicked(QCPAbstractPlottable* plottable) { qDebug() << Q_FUNC_INFO << QString("Clicked on graph '%1 ").arg(plottable->name()); } void QmlCustomPlot::routeMouseEvents(QMouseEvent* event) { if(m_plot) { QMouseEvent* newEvent = new QMouseEvent( event->type(), event->position(), event->scenePosition(), event->globalPosition(), event->button(), event->buttons(), event->modifiers(), event->source()); QCoreApplication::postEvent(m_plot, newEvent); } } void QmlCustomPlot::routeWheelEvents(QWheelEvent* event) { if(m_plot) { QWheelEvent* newEvent = new QWheelEvent( event->position(), event->globalPosition(), event->pixelDelta(), event->angleDelta(), event->buttons(), event->modifiers(), event->phase(), false); QCoreApplication::postEvent(m_plot, newEvent); } } void QmlCustomPlot::updateCustomPlotSize() { if(m_plot) { const QRect r(0, 0, int(width()), int(height())); m_plot->setGeometry(r); m_plot->setViewport(r); } } void QmlCustomPlot::onCustomReplot() { // qDebug() << Q_FUNC_INFO; m_fpsCounter++; update(); }