Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Solved Changing the content of a QVector in a C++ model doesn’t trigger the QML bindings between the model and the custom C++ component used as a delegate

    QML and Qt Quick
    2
    4
    100
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • J
      JL SABATIER last edited by

      Good Morning,

      Here is my problem: Changing the content of a QVector in a C++ model doesn’t trigger the QML bindings between the model and the custom C++ component used as a delegate

      I’ve got a QVector in my C++ model. I’ve got a C++ custom component based on a QQuickPaintedItem.
      Adding a value in the vector of the model doesn’t trigger the bindings between the model and the component.

      Context :

      I’m trying to draw the successive results from a measurement instrument.
      This makes a curve displayed with a QQuickPaintedItem.

      I’ve got a « VolmeterChannel » class, in which I’m defining a « results » property that is accessible to the QML.
      (NB : my Voltmeter class has two channels, managed by two member classes VoltmeterChannel).

      Class VoltmeterChannel : public QObject {
          Q_OBJECT
          …
          Q_PROPERTY (QVector<QPointF> results READ get_results WRITE set_results NOTIFY resultsChanged)
          …
          QVector<QPoint> m_results ;
          …
      }
      

      Every time I get a result from the Voltmeter, I’m adding the last measurement to my result vector :

      void VoltmeterChannel::setResult(int channel, qreal result) {
          static int x=0;        
          if (m_results.count() >= NB_SAMPLES)
              m_results.removeLast();
          m_results(QPointF(x, result));
          set_results(m_results);
          ++x;
          emit resultsChanged(m_results);
      }
      

      The QML bindings are as follow :

                          Repeater {
                              model: [
                                  Global.voltmeter.channel1,
                                  Global.voltmeter.channel2,
                              ];
                              delegate: PaintedGraph {
                                  id: _graph;
                                  xMin: _graph.object.xMin;
                                  xMax: _graph.object.xMax;
                                  yMin: _graph.object.yMin;
                                  yMax: _graph.object.yMax;
                                  points: _graph.object.results;
                                  visible: _graph.object.selected;
                                  color: {
                                      switch (_graph.object.number) {
                                      case VoltmeterSelection.CHANNEL_1: return "#FEDB00";
                                      case VoltmeterSelection.CHANNEL_2: return "#001489";
                                      }
                                      return "gray";
                                  }
                                  anchors {
                                      fill: parent;
                                      topMargin: Global.theme.spaceM;
                                      leftMargin: 2;
                                      rightMargin: 2;
                                      bottomMargin: Global.theme.spaceM;
                                  }
      
                                  readonly property VoltmeterChannel object: modelData;
                              }
                          }
      

      I found a « quick and dirty » fix to that problem, by reconstructing a whole QVector every time and using setResults(results).

      Then, the QML bindings are triggered and the curve is drawn.
      This is working but I don’t want to copy twice every value from the QVector every time I get a new result, as this is very bad coding…

      So, how could I program this so that adding a new value in the QVector will be signaled to the QQuickPaintedItem so it will continue drawing the curve?

      JKSH 1 Reply Last reply Reply Quote 0
      • JKSH
        JKSH Moderators @JL SABATIER last edited by

        @JL-SABATIER said in Changing the content of a QVector in a C++ model doesn’t trigger the QML bindings between the model and the custom C++ component used as a delegate:

        Adding a value in the vector of the model doesn’t trigger the bindings between the model and the component.

        That is expected.

        The QML bindings are not triggered by modifying a variable. The QML bindings are triggered by the NOTIFY signal.

        how could I program this so that adding a new value in the QVector will be signaled to the QQuickPaintedItem so it will continue drawing the curve?

        Emit your resultsChanged() signal every time a new value is added.

        Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

        1 Reply Last reply Reply Quote 2
        • J
          JL SABATIER last edited by JL SABATIER

          Thanks for your reply and for pointing me out where to look for the bug.
          I was trying to emit the signal, but there was a bug in the code. Which is now fixed. Thanks again.

          1 Reply Last reply Reply Quote 0
          • JKSH
            JKSH Moderators last edited by

            @JL-SABATIER You're most welcome. Happy coding!

            Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

            1 Reply Last reply Reply Quote 0
            • First post
              Last post