title: Is it the correct way to update QML from thread using multi layer signals?
body: <p>I'm writing a demo application to ease my QT learning curve. My aim is to update values from a thread which is running in background as a data generator. I wrote the QML and bind the C++ members to it using QT standard data binding approach, i.e. Q_Property. Currently the solution working as expected but wanted to confirm whether this is the correct way to implement the same.</p>
  
  <p><strong>Idea</strong></p>
  
  <ol>
  <li>Generate data in a thread (class DemoData) </li>
  <li>Emitting signal to notify another class (class VitalData) </li>
  <li>Emitting Q_Property signal (from class VitalData) to update UI</li>
  </ol>
  
  <p><strong>Query</strong></p>
  
  <ol>
  <li>Should I generate data and notify UI about the changes in a single class and send that class instance to a new thread? As I can use a single signal to update UI in this case.</li>
  <li>Based on current design is it gonna suffer from poor performance or in worst case some data can be missed at UI part due to rapid signal-slot? </li>
  </ol>
  
  <p>My aim is to keep the data generator class decoupled.</p>
  
  <p><strong>Finally the Code</strong></p>
  
  <pre><code>//A data generator class - this can be altered by some other class if neccessary
  class DemoData : public QObject
  {
      Q_OBJECT
      int nextUpdateIndex = 0;
  
  public slots:
      void generateData()
      {
          int hrValIndex = 0, spo2ValIndex = 0, respValIndex = 0, co2ValIndex = 0;
  
          while(true) {
              switch(nextUpdateIndex) {
              case 0:
                  emit valueUpdated(nextUpdateIndex, demoHRRates[hrValIndex]);
                  if(hrValIndex == ((sizeof demoHRRates) / (sizeof(int))) - 1)
                      hrValIndex = 0;
                  else
                      hrValIndex++;
                  nextUpdateIndex = 1;
                  break;
              }
              QThread::sleep(1);
          }
      }
  signals:
      //Signal to notify the UI about new value
      void valueUpdated(int index, int data);
  };
  
  
  //Class to interact with QML UI layer. This class only hold properties and it's binding 
  class VitalData : public QObject
  {
      Q_OBJECT
      Q_PROPERTY(int hrRate READ getHrRate NOTIFY hrRateChanged)
  
      public:
      int getHrRate() const {
          return m_hrRate;
      }
  
  public slots:
      void getData(int index, int value)
      {
          switch(index){
          case 0:
              m_hrRate = value;
              emit hrRateChanged();
              break;
          }
      }
  
  signals:
      //This signal actually notifies QML to update it value
      void hrRateChanged();
  };
  
  int main()
  {
      QGuiApplication app(argc, argv);
  
      //Data generator class is getting linked with UI data feeder class 
      VitalData med;
      DemoData demo;
      QObject::connect(&amp;demo, SIGNAL(valueUpdated(int, int)), &amp;med, SLOT(getData(int, int)));
  
      //Standard way to launch QML view 
      QQuickView view;
      view.rootContext()-&gt;setContextProperty("med", &amp;med);
      view.setSource(QUrl(QStringLiteral("qrc:/main.qml")));
      view.show();
  
      //Moving data generator to a background thread
      QThread thread;
      demo.moveToThread(&amp;thread);
      QObject::connect(&amp;thread, SIGNAL(started()), &amp;demo, SLOT(generateData()));
      thread.start();
  
      return app.exec();
  }
  </code></pre>
  
  <p><strong>New code for thread exit</strong></p>
  
  <pre><code>int main()
  {
      QThread thread;
      demo.moveToThread(&amp;thread);
      QObject::connect(&amp;thread, SIGNAL(started()), &amp;demo, SLOT(generateData()));
      QObject::connect(qApp, &amp;QCoreApplication::aboutToQuit, &amp;thread, [&amp;thread](){
          thread.requestInterruption();
          thread.wait();
      });
      thread.start();
  }
  
  
  class DemoData : public QObject
  {
      Q_OBJECT
  public slots:
      void generateData()
      {
         while(!QThread::currentThread()-&gt;isInterruptionRequested()) {
              switch(nextUpdateIndex) {
                  case 0:
                   break;
              }
              QThread::msleep(200);
              qDebug() &lt;&lt; "Thread running..";
          }
  
          //This quit was necessary. Otherwise even with requestInterruption call thread was not closing though the above debug log stopped
          QThread::currentThread()-&gt;quit();
      }
  };
  </code></pre>