title: Sending C++ signals to QML
body: <p>I have an int available via <code>WiringPiI2C</code> from an ADC at a max rate of 680 times per second. I'd like to sample and forward that value at regular intervals to various GUI objects, at 200-500Hz. I've tried a couple strategies for getting C++ data types into QML, and I always seem to fall just short.</p>
  
  <p>I'm close to success with a custom Handler class and <code>Q_PROPERTY</code> macro, but the value only appears once; it does not update on screen. I can call the data using <code>myData</code> class all day in QML(console.log) or directly from the acquisition function in C++ (<code>qDebug</code>) and it updates flawlessly - I can watch the value as the ADC's analog input voltage varies ever-so-slightly. Every time I run the program, the single frozen value that shows on my screen is different than the last, thus real data must be making it to the screen. But why doesn't it update?</p>
  
  <p>Do I somehow have to run the 
  <code>emit pressureChanged</code> 
  line <strong>and</strong> point the AppEngine 
  <code>engine.rootContext()-&gt;setContextProperty("myData",myData.data());</code>
  with the same instance of DataHandler? How would I do this?</p>
  
  <p><strong>UPDATE</strong> Indeed, the <code>emit</code> line and AppEngine pointer must be within the same instance of <code>DataHandler</code>. But I'm failing to see how I can do both with one instance. Seems something is always out of scope. I tried running <code>emit</code> via a QTimer in <code>main.qml</code> and it works, but it performs terribly. I need much faster refresh rate than 5-6Hz and it slowed down the rest of the GUI functions a lot. Any help getting <code>myData</code> class's <code>pressureChanged</code> signal sent out to QML at 60+ Hz?</p>
  
  <p><em>Application output</em> </p>
  
  <pre><code>qrc:/main.qml:31: ReferenceError: myData is not defined
  
  qrc:/main.qml:31: ReferenceError: myData is not defined
  
  I'm sampling, why isn't anyone getting this???
  
  I'm sampling, why isn't anyone getting this???
  
  25771
  
  I'm sampling, why isn't anyone getting this???
  
  25686
  
  I'm sampling, why isn't anyone getting this???
  
  25752
  
  I'm sampling, why isn't anyone getting this???
  
  qml: 25763                    &lt;--- this is a manual button push on screen
  
  I'm sampling, why isn't anyone getting this???
  
  qml: 25702                    &lt;--- this is a manual button push on screen
  
  I'm sampling, why isn't anyone getting this???
  
  25751
  </code></pre>
  
  <p>Why does QML allow me to use <code>myData</code> to send data to console, but not allow me to use <code>myData</code> as a property to manipulate QML objects?</p>
  
  <p>Is there a much easier way to get simple data types (in my case I will have two integers) into QML constantly updating various text objects on screen?</p>
  
  <p><a href="https://stackoverflow.com/questions/28239079/qml-binding-not-updating">This post</a> came close to helping me understand what's going on, and I suspect my problem is closely related to what's said there: that is, somehow my binding isn't valid and thus only calls the function <code>DataHandler::getPressure</code> 1 time.</p>
  
  <p>I tried following <a href="http://doc.qt.io/qt-4.8/qml-extending-tutorial-index.html" rel="nofollow noreferrer">this tutorial</a>, but it's a different situation (creating a class object in QML from C++, all I want is to move 1 data type to QML), so I wasn't capable enough to apply it to my problem very well...</p>
  
  <p>I've tried for days now... 3 ways of instantiating <code>myData</code>, tried with/without <code>QScopedPointer</code>, tried various ways of accessing <code>myData</code> within QML... I'm going out of my mind, please help! I appeal to the Gods of StackOverflow, for my stack doth truly overflow with ignorance...</p>
  
  <p><em>datahandler.h</em></p>
  
  <pre><code>#ifndef DATAHANDLER_H
  #define DATAHANDLER_H
  
  #include &lt;QObject&gt;
  #include &lt;QPoint&gt;
  #include &lt;QDebug&gt;
  
  class DataHandler : public QObject
  {
      Q_OBJECT
      Q_PROPERTY(int pressure READ getPressure NOTIFY pressureChanged)
  
  public:
      explicit DataHandler(QObject *parent = 0);
  
      void setupPressure();
      int getPressureSample();
      int getPressure();
      void publishPressure();
  
  signals:
      void pressureChanged();
  
  };
  
  #endif // DATAHANDLER_H
  </code></pre>
  
  <p>important bits of
  <em>datahandler.cpp</em></p>
  
  <pre><code>#include &lt;wiringPi.h&gt;
  #include &lt;wiringPiI2C.h&gt;
  #include "datahandler.h"
  
  #define SAMPLES 10
  
  DataHandler::DataHandler(QObject *parent) : QObject(parent)
  {
  
  }
  
  int DataHandler::getPressure() {
      int totalSum = 0;
      for (int i = 0; i &lt; SAMPLES; i++){
          totalSum += getPressureSample();
          delay(5);    // Sampling at ~200Hz, the ADC itself maxes at 680Hz so don't sample faster than that.
      }
      qDebug() &lt;&lt; "I'm sampling, why isn't anyone getting this update???";
      return totalSum/SAMPLES;
  }
  
  void DataHandler::publishPressure() {
      emit pressureChanged();
  }
  </code></pre>
  
  <p>important bits of <em>main.cpp</em></p>
  
  <pre><code>#include &lt;QCursor&gt;
  #include &lt;QGuiApplication&gt;
  #include &lt;QQmlApplicationEngine&gt;
  #include &lt;QQmlContext&gt;
  #include &lt;wiringPi.h&gt;
  #include &lt;wiringPiI2C.h&gt;
  #include "functions.h"
  #include "datahandler.h"
  
  PI_THREAD(updatePressure)
  {
      DataHandler pressureData(new DataHandler);
      while (true){
          delay(500);
          pressureData.publishPressure();
          qDebug() &lt;&lt; pressureData.getPressure();
      }
  }
  
  int main(int argc, char *argv[])
  {
      QGuiApplication app(argc, argv);
  
      wiringPiSetup();
      DataHandler().setupPressure();
  
      app.setOverrideCursor( QCursor( Qt::BlankCursor ) );    //Hide the cursor, no one needs that thing showing!
  
      QScopedPointer&lt;Functions&gt; myFunctions(new Functions);
      QScopedPointer&lt;DataHandler&gt; myData(new DataHandler);
  
      QQmlApplicationEngine engine;
      engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
  
      engine.rootContext()-&gt;setContextProperty("myFunctions",myFunctions.data());
      engine.rootContext()-&gt;setContextProperty("myData",myData.data());
  
      piThreadCreate(updatePressure);
  
      return app.exec();
  }
  </code></pre>
  
  <p>important bits of <em>main.qml</em></p>
  
  <pre><code>import QtQuick 2.7
  import QtQuick.Window 2.2
  import QtQuick.Controls 2.0
  import QtQuick.Controls.Styles 1.4
  import QtQuick.Extras 1.4
  
  //DECLARATIVE CONTENT
  Window {
      id: myWindow
      visible: true
      width: 800
      height: 480
      title: qsTr("Hello World")
      Item {
          focus: true
          Keys.onEscapePressed: myWindow.close()
          Keys.onSpacePressed: console.log("HOW?")
      }
  
      MainForm {
          id: root
          anchors.fill: parent
          property var shiftArray: 0
          property var tumblerArray: noteSelector.array
  
          Text {
              id: testText
              z: 9
              anchors.fill: parent
              color: "#FF0000"
              text: myData.pressure
          }
  
          customPressureClick.onClicked: {
              console.log(myData.pressure)
              toggleCustomPressureState()
              attemptCustomPressure()
          }
      }
  }
  </code></pre>
  
  <p><strong>EXTRA INFO</strong>
  As you can see above, I created a <code>PI_THREAD</code> to constantly call the <code>publishPressure</code> function which is just my way of emitting the signal from outside the class. I suppose I could somehow use <code>QTimer</code> or some other method if that's what's screwing this up.</p>
  
  <p>I used <code>qDebug()</code> to prove that the PI_THREAD is indeed calling <code>publishPressure</code> regularly, slowed it down to 500ms for sanity sake. I know the C++ data acquisition is successful because I've watched it crank out data to console at 500Hz. I know the emit function is reached, but maybe it is somehow not being executed?</p>
  
  <p>I also found it very strange that QML bindings with Keys class worked fine in Window, but <strong>not</strong> in <code>MainForm</code>. I wonder if that somehow clues to the problem</p>