title: Push QML ChartView updates from c++
body: <p>I'm trying to adapt the <a href="https://doc.qt.io/qt-5/qtcharts-qmloscilloscope-example.html" rel="noreferrer">Qt5.9 QML Oscilloscope example</a> to have the graph data pushed from c++ rather than requested from QML. Below are the pertinent sections from the QML Oscilloscope example.</p>
  
  <p>datasource.h:</p>
  
  <pre><code>#ifndef DATASOURCE_H
  #define DATASOURCE_H
  
  #include &lt;QtCore/QObject&gt;
  #include &lt;QtCharts/QAbstractSeries&gt;
  
  QT_BEGIN_NAMESPACE
  class QQuickView;
  QT_END_NAMESPACE
  
  QT_CHARTS_USE_NAMESPACE
  
  class DataSource : public QObject
  {
      Q_OBJECT
  public:
      explicit DataSource(QQuickView *appViewer, QObject *parent = 0);
  
  Q_SIGNALS:
  
  public slots:
      void generateData(int type, int rowCount, int colCount);
      void update(QAbstractSeries *series);
  
  private:
      QQuickView *m_appViewer;
      QList&lt;QVector&lt;QPointF&gt; &gt; m_data;
      int m_index;
  };
  
  #endif // DATASOURCE_H
  </code></pre>
  
  <p>datasource.cpp:</p>
  
  <pre><code>#include "datasource.h"
  #include &lt;QtCharts/QXYSeries&gt;
  #include &lt;QtCharts/QAreaSeries&gt;
  #include &lt;QtQuick/QQuickView&gt;
  #include &lt;QtQuick/QQuickItem&gt;
  #include &lt;QtCore/QDebug&gt;
  #include &lt;QtCore/QtMath&gt;
  
  QT_CHARTS_USE_NAMESPACE
  
  Q_DECLARE_METATYPE(QAbstractSeries *)
  Q_DECLARE_METATYPE(QAbstractAxis *)
  
  DataSource::DataSource(QQuickView *appViewer, QObject *parent) :
      QObject(parent),
      m_appViewer(appViewer),
      m_index(-1)
  {
      qRegisterMetaType&lt;QAbstractSeries*&gt;();
      qRegisterMetaType&lt;QAbstractAxis*&gt;();
  
      generateData(0, 5, 1024);
  }
  
  void DataSource::update(QAbstractSeries *series)
  {
      if (series) {
          QXYSeries *xySeries = static_cast&lt;QXYSeries *&gt;(series);
          m_index++;
          if (m_index &gt; m_data.count() - 1)
              m_index = 0;
  
          QVector&lt;QPointF&gt; points = m_data.at(m_index);
          // Use replace instead of clear + append, it's optimized for performance
          xySeries-&gt;replace(points);
      }
  }
  
  void DataSource::generateData(int type, int rowCount, int colCount)
  {
      // Remove previous data
      m_data.clear();
  
      // Append the new data depending on the type
      for (int i(0); i &lt; rowCount; i++) {
          QVector&lt;QPointF&gt; points;
          points.reserve(colCount);
          for (int j(0); j &lt; colCount; j++) {
              qreal x(0);
              qreal y(0);
              switch (type) {
              case 0:
                  // data with sin + random component
                  y = qSin(3.14159265358979 / 50 * j) + 0.5 + (qreal) rand() / (qreal) RAND_MAX;
                  x = j;
                  break;
              case 1:
                  // linear data
                  x = j;
                  y = (qreal) i / 10;
                  break;
              default:
                  // unknown, do nothing
                  break;
              }
              points.append(QPointF(x, y));
          }
          m_data.append(points);
      }
  }
  </code></pre>
  
  <p>main.cpp:</p>
  
  <pre><code>#include &lt;QtWidgets/QApplication&gt;
  #include &lt;QtQml/QQmlContext&gt;
  #include &lt;QtQuick/QQuickView&gt;
  #include &lt;QtQml/QQmlEngine&gt;
  #include &lt;QtCore/QDir&gt;
  #include "datasource.h"
  
  int main(int argc, char *argv[])
  {
      // Qt Charts uses Qt Graphics View Framework for drawing, therefore 
  QApplication must be used.
      QApplication app(argc, argv);
  
      QQuickView viewer;
  
      // The following are needed to make examples run without having to install the module
      // in desktop environments.
  #ifdef Q_OS_WIN
      QString extraImportPath(QStringLiteral("%1/../../../../%2"));
  #else
      QString extraImportPath(QStringLiteral("%1/../../../%2"));
  #endif
      viewer.engine()-&gt;addImportPath(extraImportPath.arg(QGuiApplication::applicationDirPath(),
                                    QString::fromLatin1("qml")));
      //QObject::connect(viewer.engine(), &amp;QQmlEngine::quit, &amp;viewer, &amp;QWindow::close);
  
      viewer.setTitle(QStringLiteral("QML Oscilloscope"));
  
      DataSource dataSource(&amp;viewer);
      viewer.rootContext()-&gt;setContextProperty("dataSource", &amp;dataSource);
  
      viewer.setSource(QUrl("qrc:/qml/qmloscilloscope/main.qml"));
      viewer.setResizeMode(QQuickView::SizeRootObjectToView);
      viewer.setColor(QColor("#404040"));
      viewer.show();
  
      return app.exec();
  }
  </code></pre>
  
  <p>ScopeView.qml:</p>
  
  <pre><code>import QtQuick 2.0
  import QtCharts 2.1
  
  ChartView {
      id: chartView
      animationOptions: ChartView.NoAnimation
      theme: ChartView.ChartThemeDark
      property bool openGL: true
      property bool openGLSupported: true
      onOpenGLChanged: {
          if (openGLSupported) {
              series("signal 1").useOpenGL = openGL;
          }
      }
      Component.onCompleted: {
          if (!series("signal 1").useOpenGL) {
              openGLSupported = false
              openGL = false
          }
      }
  
      ValueAxis {
          id: axisY1
          min: -1
          max: 4
      }
  
      ValueAxis {
          id: axisX
          min: 0
          max: 1024
      }
  
      LineSeries {
          id: lineSeries1
          name: "signal 1"
          axisX: axisX
          axisY: axisY1
          useOpenGL: chartView.openGL
      }
  
      Timer {
          id: refreshTimer
          interval: 1 / 60 * 1000 // 60 Hz
          running: true
         repeat: true
          onTriggered: {
              dataSource.update(chartView.series(0));
          }
      }
  }
  </code></pre>
  
  <p>Rather than using the Timer in QML, I'd like to use an existing Timeout in a c++ class to push new data to the QML ChartView. I have two questions:</p>
  
  <ol>
  <li>How would I achieve this for the QML Oscilloscope example posted above?</li>
  <li>What format would be most suitable for the c++ data to facilitate this? I'm thinking a QVector of some sort; the data will be an integer or float with a vector index.</li>
  </ol>