Hi, i am a beginner in c++ and Qt, and I want to use QCustomPlot in QML to plot a the realtimeData example.
So I found a method to use QCustomPlot in QML on https://www.qcustomplot.com/index.php/support/forum/172
and I added the code used in the example like this:
customplotiem.h :
#pragma once #include <QtQuick> #include "../../qcustomplot.h" class QCustomPlot; class CustomPlotItem : public QQuickPaintedItem { Q_OBJECT public: CustomPlotItem( QQuickItem* parent = 0 ); virtual ~CustomPlotItem(); void paint( QPainter* painter ); Q_INVOKABLE void initCustomPlot(); void setupPlot(QCustomPlot* customPlot ); protected: void routeMouseEvents( QMouseEvent* event ); virtual void mousePressEvent( QMouseEvent* event ); virtual void mouseReleaseEvent( QMouseEvent* event ); virtual void mouseMoveEvent( QMouseEvent* event ); virtual void mouseDoubleClickEvent( QMouseEvent* event ); void setupQuadraticDemo( QCustomPlot* customPlot ); private: QCustomPlot* m_CustomPlot; QTimer* dataTimer; private slots: void graphClicked(QCPAbstractPlottable* plottable); void onCustomReplot(); void updateCustomPlotSize(); void realtimeDataSlot(QCustomPlot* customPlot); };
customplotitem.cpp :
#include "CustomPlotItem.h" #include "../../qcustomplot.h" #include <QDebug> CustomPlotItem::CustomPlotItem( QQuickItem* parent ) : QQuickPaintedItem( parent ), m_CustomPlot( nullptr ) { setFlag( QQuickItem::ItemHasContents, true ); // setRenderTarget(QQuickPaintedItem::FramebufferObject); // setAcceptHoverEvents(true); setAcceptedMouseButtons( Qt::AllButtons ); connect( this, &QQuickPaintedItem::widthChanged, this, &CustomPlotItem::updateCustomPlotSize ); connect( this, &QQuickPaintedItem::heightChanged, this, &CustomPlotItem::updateCustomPlotSize ); } CustomPlotItem::~CustomPlotItem() { delete m_CustomPlot; m_CustomPlot = nullptr; } void CustomPlotItem::initCustomPlot() { m_CustomPlot = new QCustomPlot(); updateCustomPlotSize(); setupPlot(m_CustomPlot); realtimeDataSlot(m_CustomPlot); //setupQuadraticDemo(m_CustomPlot); connect( m_CustomPlot, &QCustomPlot::afterReplot, this, &CustomPlotItem::onCustomReplot ); m_CustomPlot->replot(); } void CustomPlotItem::setupPlot(QCustomPlot* customPlot) { customPlot->addGraph(); customPlot->graph(0)->setPen(QPen(QColor(40, 110, 255))); QSharedPointer<QCPAxisTickerTime> timeTicker(new QCPAxisTickerTime); timeTicker->setTimeFormat("%h:%m:%s"); customPlot->xAxis->setTicker(timeTicker); customPlot->axisRect()->setupFullAxesBox(); customPlot->yAxis->setRange(-1.2, 1.2); // make left and bottom axes transfer their ranges to right and top axes: connect(customPlot->xAxis, SIGNAL(rangeChanged(QCPRange)), customPlot->xAxis2, SLOT(setRange(QCPRange))); connect(customPlot->yAxis, SIGNAL(rangeChanged(QCPRange)), customPlot->yAxis2, SLOT(setRange(QCPRange))); // setup a timer that repeatedly calls MainWindow::realtimeDataSlot: dataTimer = new QTimer(this); connect(dataTimer, SIGNAL(timeout()), this, SLOT(realtimeDataSlot(m_customPlot))); dataTimer->start(10); } void CustomPlotItem::realtimeDataSlot(QCustomPlot* customPlot) { static QTime time(QTime::currentTime()); // calculate two new data points: double key = time.elapsed()/1000.0; // time elapsed since start of demo, in seconds static double lastPointKey = 0; if (key-lastPointKey > 0.02) // at most add point every 20 ms { // add data to lines: customPlot->graph(0)->addData(key, qSin(key)+qrand()/(double)RAND_MAX*1*qSin(key/0.3843)); //ui->customPlot->graph(1)->addData(key, qCos(key)+qrand()/(double)RAND_MAX*0.5*qSin(key/0.4364)); // rescale value (vertical) axis to fit the current data: customPlot->graph(0)->rescaleValueAxis(); //ui->customPlot->graph(1)->rescaleValueAxis(true); lastPointKey = key; } // make key axis range scroll with the data (at a constant range size of 8): customPlot->xAxis->setRange(key, 8, Qt::AlignRight); customPlot->replot(); } void CustomPlotItem::paint( QPainter* painter ) { if (m_CustomPlot) { QPixmap picture( boundingRect().size().toSize() ); QCPPainter qcpPainter( &picture ); //m_CustomPlot->replot(); m_CustomPlot->toPainter( &qcpPainter ); painter->drawPixmap( QPoint(), picture ); } } void CustomPlotItem::mousePressEvent( QMouseEvent* event ) { qDebug() << Q_FUNC_INFO; routeMouseEvents( event ); } void CustomPlotItem::mouseReleaseEvent( QMouseEvent* event ) { qDebug() << Q_FUNC_INFO; routeMouseEvents( event ); } void CustomPlotItem::mouseMoveEvent( QMouseEvent* event ) { routeMouseEvents( event ); } void CustomPlotItem::mouseDoubleClickEvent( QMouseEvent* event ) { qDebug() << Q_FUNC_INFO; routeMouseEvents( event ); } void CustomPlotItem::graphClicked( QCPAbstractPlottable* plottable ) { qDebug() << Q_FUNC_INFO << QString( "Clicked on graph '%1 " ).arg( plottable->name() ); } void CustomPlotItem::routeMouseEvents( QMouseEvent* event ) { if (m_CustomPlot) { QMouseEvent* newEvent = new QMouseEvent( event->type(), event->localPos(), event->button(), event->buttons(), event->modifiers() ); //QCoreApplication::sendEvent( m_CustomPlot, newEvent ); QCoreApplication::postEvent( m_CustomPlot, newEvent ); } } void CustomPlotItem::updateCustomPlotSize() { if (m_CustomPlot) { m_CustomPlot->setGeometry( 0, 0, width(), height() ); } } void CustomPlotItem::onCustomReplot() { qDebug() << Q_FUNC_INFO; update(); } void CustomPlotItem::setupQuadraticDemo( QCustomPlot* customPlot ) { // make top right axes clones of bottom left axes: QCPAxisRect* axisRect = customPlot->axisRect(); // generate some data: QVector<double> x( 101 ), y( 101 ); // initialize with entries 0..100 QVector<double> lx( 101 ), ly( 101 ); // initialize with entries 0..100 for (int i = 0; i < 101; ++i) { x[i] = i / 50.0 - 1; // x goes from -1 to 1 y[i] = x[i] * x[i]; // let's plot a quadratic function lx[i] = i / 50.0 - 1; // ly[i] = lx[i]; // linear } // create graph and assign data to it: customPlot->addGraph(); customPlot->graph( 0 )->setPen( QPen( Qt::red ) ); customPlot->graph( 0 )->setPen( QPen( Qt::blue, 2 ) ); customPlot->graph( 0 )->setData( x, y ); customPlot->addGraph(); customPlot->graph( 1 )->setPen( QPen( Qt::magenta ) ); customPlot->graph( 1 )->setPen( QPen( Qt::blue, 2 ) ); customPlot->graph( 1 )->setData( lx, ly ); // give the axes some labels: customPlot->xAxis->setLabel( "x" ); customPlot->yAxis->setLabel( "y" ); // set axes ranges, so we see all data: customPlot->xAxis->setRange( -1, 1 ); customPlot->yAxis->setRange( -1, 1 ); customPlot ->setInteractions( QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables ); connect( customPlot, SIGNAL(plottableClick(QCPAbstractPlottable*, QMouseEvent*)), this, SLOT(graphClicked( QCPAbstractPlottable*))); }
main.cpp :
#include <QApplication> #include "mainwindow.h" #include <QtWidgets/QApplication> #include <QtQuick> #include "CustomPlotItem.h" int main(int argc, char *argv[]) { #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) QApplication::setGraphicsSystem("raster"); #endif QApplication a(argc, argv); MainWindow w; //w.show(); qmlRegisterType<CustomPlotItem>("CustomPlot",1,0,"CustomPlotItem"); QQuickView view(QUrl("qrc:/graph.qml")); view.setResizeMode(QQuickView::SizeRootObjectToView); view.resize(500,500); view.show(); return a.exec(); }
main.qml
import QtQuick 2.3 import QtQuick.Controls 1.2 import CustomPlot 1.0 Item { CustomPlotItem { id: customPlot anchors.fill: parent Component.onCompleted: initCustomPlot() } }
But it did nothing and nothing be plot.
Any ideas ?
Thanks