Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. updating elements in a repeater?
Forum Updated to NodeBB v4.3 + New Features

updating elements in a repeater?

Scheduled Pinned Locked Moved Solved QML and Qt Quick
43 Posts 5 Posters 12.8k Views 4 Watching
  • 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.
  • mzimmersM Offline
    mzimmersM Offline
    mzimmers
    wrote on last edited by mzimmers
    #1

    Hi all -

    I know this code is coyote-ugly, but bear with me:

    Column {
        id: myColumn
        property var myArray: []
        property var cellXArray: [25, 25, 102];
        property var cellYArray: [105, 15, 125];
        property var cellColorArray: ['red', 'red', 'red']
        Repeater {
    
            model: 3//myColumn.myArray.length
            Bottle {
                cellX: myColumn.cellXArray[index]
                cellY: myColumn.cellYArray[index]
                cellColor: myColumn.cellColorArray[index]
            }
        }
    }
    

    When this component becomes active, it calls a function that includes this:

    myColumn.cellColorArray[0] = 'green'
    

    How do I get this change to be reflected in the first element of the repeater?

    Thanks...

    EDIT: oh: Bottle is just a component I made, based on a Rectangle.

    kshegunovK 1 Reply Last reply
    0
    • eyllanescE Offline
      eyllanescE Offline
      eyllanesc
      wrote on last edited by eyllanesc
      #2

      Models of type number cannot be updated since they do not notify the change, those of type list are only updated if the entire list is replaced, so in your case it is better to use a ListModel:

          ListModel {
              id: bottlemodel
      
              ListElement {
                  x: 25
                  y: 105
                  color: "red"
              }
      
              ListElement {
                  x: 25
                  y: 15
                  color: "red"
              }
      
              ListElement {
                  x: 102
                  y: 125
                  color: "red"
              }
      
          }
      
          Repeater {
              model: bottlemodel
      
              Rectangle {
                  x: model.x
                  y: model.y
                  width: 20
                  height: 20
                  color: model.color
              }
      
          }
          Component.onCompleted: () => {
              bottlemodel.setProperty(0, "color", "green");
          }
      

      If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

      1 Reply Last reply
      3
      • jeremy_kJ Offline
        jeremy_kJ Offline
        jeremy_k
        wrote on last edited by
        #3

        Repeater.itemAt(index) will return the item, at which point the code can assign to its properties. Another option is to bind the property in the delegate to a property in something not managed by the Repeater. Creating a binding is more aesthetically pleasing to me. itemAt() should be more efficient if the goal is to change one item out of many.

        Asking a question about code? http://eel.is/iso-c++/testcase/

        1 Reply Last reply
        2
        • mzimmersM mzimmers

          Hi all -

          I know this code is coyote-ugly, but bear with me:

          Column {
              id: myColumn
              property var myArray: []
              property var cellXArray: [25, 25, 102];
              property var cellYArray: [105, 15, 125];
              property var cellColorArray: ['red', 'red', 'red']
              Repeater {
          
                  model: 3//myColumn.myArray.length
                  Bottle {
                      cellX: myColumn.cellXArray[index]
                      cellY: myColumn.cellYArray[index]
                      cellColor: myColumn.cellColorArray[index]
                  }
              }
          }
          

          When this component becomes active, it calls a function that includes this:

          myColumn.cellColorArray[0] = 'green'
          

          How do I get this change to be reflected in the first element of the repeater?

          Thanks...

          EDIT: oh: Bottle is just a component I made, based on a Rectangle.

          kshegunovK Offline
          kshegunovK Offline
          kshegunov
          Moderators
          wrote on last edited by kshegunov
          #4

          See what @jeremy_k and @eyllanesc wrote. But as food for thought, doesn't this make more sense:

          Column {
              id: myColumn
              property list data: [
                  QtObject {
                      property int x: 25
                      property int y: 105
                      property string color: 'red'
                  },
                  QtObject {
                      ...
                  }
                  ...
              ]
          
              Repeater {
                  model: myColumn.data
                  Bottle {
                      cellX: modelData.x
                      cellY: modelData.y
                      cellColor: modelData.color
                  }
              }
          }

          Read and abide by the Qt Code of Conduct

          1 Reply Last reply
          1
          • mzimmersM Offline
            mzimmersM Offline
            mzimmers
            wrote on last edited by mzimmers
            #5

            Lots of good options here; thanks, guys.

            @eyllanesc: my OP might have been a bit misleading in that, when this view is presented, there will be lots more changes; I was just giving an example. There will be 16-19 bottles displayed, and each will have its color updated, and some other attributes set/updated. I don't know if this changes your opinion on how to approach this problem.

            I removed your Component.oncompleted in favor of something like this:

                onVisibleChanged: {
                    var modelSize = bottleModel.count
                    var i;
                    var color;
                    for (i = 0; i < modelSize; ++i) {
                        color = (myColumn.myArray[i].volume > myColumn.myArray[i].amountNeeded) ? "green" : "red"
                        bottleRepeater.itemAt(i).cellColor = color
                }
            

            This ensures a refresh whenever the view is activated.

            @jeremy_k I tried your first suggestion, and it works great. Could you possibly elaborate on your second suggestion? I'd like to hear more about it.

            @kshegunov your approach looks great, but I'm curious as to exactly what about it you prefer over the others.

            Thanks again...this has been very helpful.

            eyllanescE kshegunovK 2 Replies Last reply
            0
            • mzimmersM mzimmers

              Lots of good options here; thanks, guys.

              @eyllanesc: my OP might have been a bit misleading in that, when this view is presented, there will be lots more changes; I was just giving an example. There will be 16-19 bottles displayed, and each will have its color updated, and some other attributes set/updated. I don't know if this changes your opinion on how to approach this problem.

              I removed your Component.oncompleted in favor of something like this:

                  onVisibleChanged: {
                      var modelSize = bottleModel.count
                      var i;
                      var color;
                      for (i = 0; i < modelSize; ++i) {
                          color = (myColumn.myArray[i].volume > myColumn.myArray[i].amountNeeded) ? "green" : "red"
                          bottleRepeater.itemAt(i).cellColor = color
                  }
              

              This ensures a refresh whenever the view is activated.

              @jeremy_k I tried your first suggestion, and it works great. Could you possibly elaborate on your second suggestion? I'd like to hear more about it.

              @kshegunov your approach looks great, but I'm curious as to exactly what about it you prefer over the others.

              Thanks again...this has been very helpful.

              eyllanescE Offline
              eyllanescE Offline
              eyllanesc
              wrote on last edited by
              #6

              @mzimmers What is myArray? I think that if you provide a minimal verifiable example you could give yourself a much more optimal answer. For example I suspect that "myArray" may be the Repeater model, and the color should not be a new property but just a binding something like: color: modelData.volume > modelData.amountNeeded ? "green" : "red"

              If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

              mzimmersM 1 Reply Last reply
              0
              • eyllanescE eyllanesc

                @mzimmers What is myArray? I think that if you provide a minimal verifiable example you could give yourself a much more optimal answer. For example I suspect that "myArray" may be the Repeater model, and the color should not be a new property but just a binding something like: color: modelData.volume > modelData.amountNeeded ? "green" : "red"

                mzimmersM Offline
                mzimmersM Offline
                mzimmers
                wrote on last edited by
                #7

                @eyllanesc

                    Column {
                      id: myColumn
                      property var myArray: []
                ...
                    function updateArray() {
                      var arr = []
                      BottleList.getBottleList().forEach(function (bottle) {
                        arr.push(bottle)
                      }, this)
                      myColumn.myArray = arr
                    }
                

                It is (indirectly) constructed from a C++ list of stuct Bottle (not to be confused with the Bottle QML Component).

                Normally I try to give repeatable examples, but this application is a bit of a mare's nest, so I was trying to contain the information conveyed to what I felt was relevant.

                It occurs to me that all the data relevant to this view falls into 2 categories:

                1. data that is innate to the actual bottles (name, fill level, capacity, ingredient, etc)
                2. data that is only relevant to the UI (size on screen, position)

                I'm trying to keep these separate (maybe this isn't such a good idea)...anything from the first category, I try to get from my C++ model. Anything in the second category, I'm happy to contain within the QML code.

                eyllanescE 1 Reply Last reply
                0
                • mzimmersM mzimmers

                  @eyllanesc

                      Column {
                        id: myColumn
                        property var myArray: []
                  ...
                      function updateArray() {
                        var arr = []
                        BottleList.getBottleList().forEach(function (bottle) {
                          arr.push(bottle)
                        }, this)
                        myColumn.myArray = arr
                      }
                  

                  It is (indirectly) constructed from a C++ list of stuct Bottle (not to be confused with the Bottle QML Component).

                  Normally I try to give repeatable examples, but this application is a bit of a mare's nest, so I was trying to contain the information conveyed to what I felt was relevant.

                  It occurs to me that all the data relevant to this view falls into 2 categories:

                  1. data that is innate to the actual bottles (name, fill level, capacity, ingredient, etc)
                  2. data that is only relevant to the UI (size on screen, position)

                  I'm trying to keep these separate (maybe this isn't such a good idea)...anything from the first category, I try to get from my C++ model. Anything in the second category, I'm happy to contain within the QML code.

                  eyllanescE Offline
                  eyllanescE Offline
                  eyllanesc
                  wrote on last edited by
                  #8

                  @mzimmers I think that if it is necessary that you provide the implementation of Bottle and that BottleList since the implementation of the view depends on the implementation of the data methods. In the case of Qt classes, it is not necessary to provide the source code because the docs replace it, but in your case we do not know the code. Provide the code and then we will point you to a better solution. On the other hand that is cellY, cellY since a Column does not have that attribute.

                  If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

                  1 Reply Last reply
                  0
                  • mzimmersM Offline
                    mzimmersM Offline
                    mzimmers
                    wrote on last edited by
                    #9

                    Sure:

                    struct Bottle {
                      Q_GADGET
                      Q_PROPERTY(quint32 volume MEMBER m_volume)
                      Q_PROPERTY(quint32 amountNeeded MEMBER m_amountNeeded)
                      Q_PROPERTY(int position MEMBER m_position)
                      Q_PROPERTY(QString name MEMBER m_name)
                      Q_PROPERTY(ReagentBottleType bottleType MEMBER m_bottleType)
                     public:
                      quint32 m_volume;                // amount in bottle (in uL)
                      quint32 m_amountNeeded;          // amount needed for synth (in uL)
                      int m_position;                  // still figuring this one out
                      QString m_name;                  // name of the reagent
                      ReagentBottleType m_bottleType;  // bottle type.
                    };
                    ...
                    typedef QVector<Bottle> Bottles;
                    ...
                    class BottleList : public QObject {
                      Q_OBJECT
                     private:
                      Bottles m_bottleList;
                      ...
                    
                    eyllanescE 1 Reply Last reply
                    0
                    • mzimmersM mzimmers

                      Sure:

                      struct Bottle {
                        Q_GADGET
                        Q_PROPERTY(quint32 volume MEMBER m_volume)
                        Q_PROPERTY(quint32 amountNeeded MEMBER m_amountNeeded)
                        Q_PROPERTY(int position MEMBER m_position)
                        Q_PROPERTY(QString name MEMBER m_name)
                        Q_PROPERTY(ReagentBottleType bottleType MEMBER m_bottleType)
                       public:
                        quint32 m_volume;                // amount in bottle (in uL)
                        quint32 m_amountNeeded;          // amount needed for synth (in uL)
                        int m_position;                  // still figuring this one out
                        QString m_name;                  // name of the reagent
                        ReagentBottleType m_bottleType;  // bottle type.
                      };
                      ...
                      typedef QVector<Bottle> Bottles;
                      ...
                      class BottleList : public QObject {
                        Q_OBJECT
                       private:
                        Bottles m_bottleList;
                        ...
                      
                      eyllanescE Offline
                      eyllanescE Offline
                      eyllanesc
                      wrote on last edited by eyllanesc
                      #10

                      @mzimmers The following is a trivial example:

                      main.cpp

                      #include <QGuiApplication>
                      #include <QQmlApplicationEngine>
                      #include <QQmlContext>
                      
                      struct Bottle {
                          Q_GADGET
                          Q_PROPERTY(quint32 volume MEMBER m_volume)
                          Q_PROPERTY(quint32 amountNeeded MEMBER m_amountNeeded)
                          Q_PROPERTY(int position MEMBER m_position)
                          Q_PROPERTY(QString name MEMBER m_name)
                      public:
                          quint32 m_volume;                // amount in bottle (in uL)
                          quint32 m_amountNeeded;          // amount needed for synth (in uL)
                          int m_position;                  // still figuring this one out
                          QString m_name;                  // name of the reagent
                      };
                      
                      typedef QVector<Bottle> Bottles;
                      
                      class BottleManager: public QObject{
                          Q_OBJECT
                          Q_PROPERTY(QVariantList bottles READ bottles NOTIFY bottlesChanged)
                      public:
                          QVariantList bottles() const{
                              return m_bottles;
                          }
                          void append(const Bottle & bottle){
                              m_bottles << QVariant::fromValue(bottle);
                              Q_EMIT bottlesChanged();
                          }
                          void clear(){
                              m_bottles.clear();
                              Q_EMIT bottlesChanged();
                          }
                      Q_SIGNALS:
                          void bottlesChanged();
                      private:
                          QVariantList m_bottles;
                      };
                      
                      int main(int argc, char *argv[])
                      {
                      #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
                          QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
                      #endif
                      
                          BottleManager manager;
                          manager.append({100, 10, 100, "item1"});
                          manager.append({10, 100, 10, "item2"});
                          manager.append({100, 10, 10, "item3"});
                          manager.append({100, 10, 10, "item4"});
                          manager.append({10, 100, 10, "item5"});
                      
                          QGuiApplication app(argc, argv);
                      
                          QQmlApplicationEngine engine;
                          engine.rootContext()->setContextProperty("bottlesmanager", &manager);
                          const QUrl url(QStringLiteral("qrc:/main.qml"));
                          QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                                           &app, [url](QObject *obj, const QUrl &objUrl) {
                              if (!obj && url == objUrl)
                                  QCoreApplication::exit(-1);
                          }, Qt::QueuedConnection);
                          engine.load(url);
                      
                          return app.exec();
                      }
                      
                      #include "main.moc"
                      

                      main.qml

                      import QtQuick 2.12
                      import QtQuick.Window 2.12
                      
                      Window {
                          width: 640
                          height: 480
                          visible: true
                          title: qsTr("Hello World")
                          Column{
                              Repeater{
                                  model: bottlesmanager.bottles
                                  Rectangle{
                                      width: 100
                                      height: 100
                                      border.color: "black"
                                      color: model.modelData.volume < model.modelData.amountNeeded ? "green": "red"
                                      Text{
                                          anchors.centerIn: parent
                                          text: model.modelData.name
                                      }
                                  }
                              }
                          }
                      }
                      

                      Screenshot_20210311_142255.png

                      If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

                      1 Reply Last reply
                      1
                      • mzimmersM Offline
                        mzimmersM Offline
                        mzimmers
                        wrote on last edited by mzimmers
                        #11

                        Thanks for the detailed example. I understand most of it, but...what is this for?

                         QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                                             &app, [url](QObject *obj, const QUrl &objUrl) {
                                if (!obj && url == objUrl)
                                    QCoreApplication::exit(-1);
                            }, Qt::QueuedConnection);
                        
                        eyllanescE 1 Reply Last reply
                        0
                        • mzimmersM mzimmers

                          Thanks for the detailed example. I understand most of it, but...what is this for?

                           QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                                               &app, [url](QObject *obj, const QUrl &objUrl) {
                                  if (!obj && url == objUrl)
                                      QCoreApplication::exit(-1);
                              }, Qt::QueuedConnection);
                          
                          eyllanescE Offline
                          eyllanescE Offline
                          eyllanesc
                          wrote on last edited by
                          #12

                          @mzimmers hmm, that's part of the current Qt template for those kinds of projects. Previously it was verified that there is at least one rootObject but that does not guarantee that it works, so now it is preferred to verify using the objectCreated signal

                          If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

                          mzimmersM 1 Reply Last reply
                          0
                          • eyllanescE eyllanesc

                            @mzimmers hmm, that's part of the current Qt template for those kinds of projects. Previously it was verified that there is at least one rootObject but that does not guarantee that it works, so now it is preferred to verify using the objectCreated signal

                            mzimmersM Offline
                            mzimmersM Offline
                            mzimmers
                            wrote on last edited by
                            #13

                            @eyllanesc ah...OK, that's being taken care of elsewhere in the project setting, so I don't need to deal with that. (I do set the context property.)

                            So, I guess the advantage of this approach is, no duplication of data?

                            Nit: your comparison of volume/amountNeeded is backwards.

                            1 Reply Last reply
                            0
                            • mzimmersM mzimmers

                              Lots of good options here; thanks, guys.

                              @eyllanesc: my OP might have been a bit misleading in that, when this view is presented, there will be lots more changes; I was just giving an example. There will be 16-19 bottles displayed, and each will have its color updated, and some other attributes set/updated. I don't know if this changes your opinion on how to approach this problem.

                              I removed your Component.oncompleted in favor of something like this:

                                  onVisibleChanged: {
                                      var modelSize = bottleModel.count
                                      var i;
                                      var color;
                                      for (i = 0; i < modelSize; ++i) {
                                          color = (myColumn.myArray[i].volume > myColumn.myArray[i].amountNeeded) ? "green" : "red"
                                          bottleRepeater.itemAt(i).cellColor = color
                                  }
                              

                              This ensures a refresh whenever the view is activated.

                              @jeremy_k I tried your first suggestion, and it works great. Could you possibly elaborate on your second suggestion? I'd like to hear more about it.

                              @kshegunov your approach looks great, but I'm curious as to exactly what about it you prefer over the others.

                              Thanks again...this has been very helpful.

                              kshegunovK Offline
                              kshegunovK Offline
                              kshegunov
                              Moderators
                              wrote on last edited by kshegunov
                              #14

                              @mzimmers said in updating elements in a repeater?:

                              @kshegunov your approach looks great, but I'm curious as to exactly what about it you prefer over the others.

                              Because I assume that at some later time you/I/whoever are/am/is going to want to tie it with a C++ backend. So, I'd rather not stick to QtQuick items, but either directly expose an array of QObejcts or define a QAbstractItemModel and use that. It's not better, it's just that I've learned over the years that requirements have this peculiar property of changing themselves midway.

                              @mzimmers said in updating elements in a repeater?:

                              Thanks for the detailed example. I understand most of it, but...what is this for?

                              QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                                                   &app, [url](QObject *obj, const QUrl &objUrl) {
                                      if (!obj && url == objUrl)
                                          QCoreApplication::exit(-1);
                                  }, Qt::QueuedConnection);
                              

                              This is what is emitted when a quick item is created through a component that's loaded from a file (either your main file, or with a Loader). It's a dummy as it just kills the application if there's an error, but you could possibly attach there to handle the failure if you wish and if you allow your UI to, say, be edited without recompiling the application.

                              @eyllanesc ah...OK, that's being taken care of elsewhere in the project setting, so I don't need to deal with that. (I do set the context property.)

                              So, I guess the advantage of this approach is, no duplication of data?

                              You're now being naive. ;)

                              This:

                              Text{
                                  anchors.centerIn: parent
                                  text: model.modelData.name
                              }
                              

                              copies the QString (a shallow copy).

                              Read and abide by the Qt Code of Conduct

                              mzimmersM 1 Reply Last reply
                              1
                              • kshegunovK kshegunov

                                @mzimmers said in updating elements in a repeater?:

                                @kshegunov your approach looks great, but I'm curious as to exactly what about it you prefer over the others.

                                Because I assume that at some later time you/I/whoever are/am/is going to want to tie it with a C++ backend. So, I'd rather not stick to QtQuick items, but either directly expose an array of QObejcts or define a QAbstractItemModel and use that. It's not better, it's just that I've learned over the years that requirements have this peculiar property of changing themselves midway.

                                @mzimmers said in updating elements in a repeater?:

                                Thanks for the detailed example. I understand most of it, but...what is this for?

                                QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                                                     &app, [url](QObject *obj, const QUrl &objUrl) {
                                        if (!obj && url == objUrl)
                                            QCoreApplication::exit(-1);
                                    }, Qt::QueuedConnection);
                                

                                This is what is emitted when a quick item is created through a component that's loaded from a file (either your main file, or with a Loader). It's a dummy as it just kills the application if there's an error, but you could possibly attach there to handle the failure if you wish and if you allow your UI to, say, be edited without recompiling the application.

                                @eyllanesc ah...OK, that's being taken care of elsewhere in the project setting, so I don't need to deal with that. (I do set the context property.)

                                So, I guess the advantage of this approach is, no duplication of data?

                                You're now being naive. ;)

                                This:

                                Text{
                                    anchors.centerIn: parent
                                    text: model.modelData.name
                                }
                                

                                copies the QString (a shallow copy).

                                mzimmersM Offline
                                mzimmersM Offline
                                mzimmers
                                wrote on last edited by
                                #15

                                @kshegunov said in updating elements in a repeater?:

                                Because I assume that at some later time you/I/whoever are/am/is going to want to tie it with a C++ backend. So, I'd rather not stick to QtQuick items, but either directly expose an array of QObejcts or define a QAbstractItemModel and use that.

                                Agreed 100%. In this spirit, I'm trying to restructure my application like this:

                                1. I have a struct Bottle, based on Q_GADGET. This contains information intrinsic to the bottle (size, dimensions, contents, etc.).
                                2. I have a class ReagentManager that contains a private QVector of Bottles. An object of this class is registered as a context property to make it visible to the QML.
                                3. One QML view contains a repeater for bottles, containing UI-specific information (size, screen location).

                                So...while my ReagentManager class is visible to the QML, the QVector of Bottles is not. I can write Q_INVOKABLE access routines for each of them, but I'm curious as to whether there might be a better way of doing it.

                                Thanks for any input.

                                My C++ code maintains an instance of the class ReagentManager, so I'm confident that its contents are always current. Now: how best to do something like this:

                                kshegunovK 1 Reply Last reply
                                0
                                • mzimmersM mzimmers

                                  @kshegunov said in updating elements in a repeater?:

                                  Because I assume that at some later time you/I/whoever are/am/is going to want to tie it with a C++ backend. So, I'd rather not stick to QtQuick items, but either directly expose an array of QObejcts or define a QAbstractItemModel and use that.

                                  Agreed 100%. In this spirit, I'm trying to restructure my application like this:

                                  1. I have a struct Bottle, based on Q_GADGET. This contains information intrinsic to the bottle (size, dimensions, contents, etc.).
                                  2. I have a class ReagentManager that contains a private QVector of Bottles. An object of this class is registered as a context property to make it visible to the QML.
                                  3. One QML view contains a repeater for bottles, containing UI-specific information (size, screen location).

                                  So...while my ReagentManager class is visible to the QML, the QVector of Bottles is not. I can write Q_INVOKABLE access routines for each of them, but I'm curious as to whether there might be a better way of doing it.

                                  Thanks for any input.

                                  My C++ code maintains an instance of the class ReagentManager, so I'm confident that its contents are always current. Now: how best to do something like this:

                                  kshegunovK Offline
                                  kshegunovK Offline
                                  kshegunov
                                  Moderators
                                  wrote on last edited by
                                  #16

                                  @mzimmers said in updating elements in a repeater?:

                                  So...while my ReagentManager class is visible to the QML, the QVector of Bottles is not. I can write Q_INVOKABLE access routines for each of them, but I'm curious as to whether there might be a better way of doing it.

                                  Make the bottles QObject instead of them being Q_GADGET and expose their properties (look up the Q_PROPERTY docs and be sure to have the notification signals). After that the QML part remains pretty much the same, the change in the QObject is going to be reflected naturally into the QML scene without anything more than you binding the properties on creation.

                                  Read and abide by the Qt Code of Conduct

                                  mzimmersM 1 Reply Last reply
                                  1
                                  • kshegunovK kshegunov

                                    @mzimmers said in updating elements in a repeater?:

                                    So...while my ReagentManager class is visible to the QML, the QVector of Bottles is not. I can write Q_INVOKABLE access routines for each of them, but I'm curious as to whether there might be a better way of doing it.

                                    Make the bottles QObject instead of them being Q_GADGET and expose their properties (look up the Q_PROPERTY docs and be sure to have the notification signals). After that the QML part remains pretty much the same, the change in the QObject is going to be reflected naturally into the QML scene without anything more than you binding the properties on creation.

                                    mzimmersM Offline
                                    mzimmersM Offline
                                    mzimmers
                                    wrote on last edited by mzimmers
                                    #17

                                    @kshegunov thanks. I'm still a little UNclear on the binding details; what would be an example of a bind using your code above?

                                    kshegunovK 1 Reply Last reply
                                    0
                                    • mzimmersM mzimmers

                                      @kshegunov thanks. I'm still a little UNclear on the binding details; what would be an example of a bind using your code above?

                                      kshegunovK Offline
                                      kshegunovK Offline
                                      kshegunov
                                      Moderators
                                      wrote on last edited by kshegunov
                                      #18
                                      Bottle {
                                          cellX: modelData.x //< If modelData is QObject, this is a property binding
                                          cellY: modelData.y
                                          cellColor: modelData.color
                                      }
                                      

                                      Read and abide by the Qt Code of Conduct

                                      mzimmersM 1 Reply Last reply
                                      1
                                      • kshegunovK kshegunov
                                        Bottle {
                                            cellX: modelData.x //< If modelData is QObject, this is a property binding
                                            cellY: modelData.y
                                            cellColor: modelData.color
                                        }
                                        
                                        mzimmersM Offline
                                        mzimmersM Offline
                                        mzimmers
                                        wrote on last edited by
                                        #19

                                        @kshegunov

                                        Trying this:

                                        struct Bottle : public QObject {
                                          Q_OBJECT
                                          Q_PROPERTY(quint32 volume MEMBER m_volume NOTIFY volumeChanged)
                                          Q_PROPERTY(quint32 minVolume MEMBER m_minVolume NOTIFY minVolumeChanged)
                                          Q_PROPERTY(quint32 amountNeeded MEMBER m_amountNeeded NOTIFY amountNeededChanged)
                                          Q_PROPERTY(int slotNumber MEMBER m_slotNumber)
                                          Q_PROPERTY(QString name MEMBER m_name)
                                          Q_PROPERTY(ReagentBottleType bottleType MEMBER m_bottleType)
                                        
                                         public:
                                          // needed to represent amounts in int, not float
                                          // because using floats causes a float-equal error
                                          // in the generated MOC file.
                                          quint32 m_volume;                // amount in bottle (in uL)
                                          quint32 m_minVolume;             // amount in bottle that can't be used (in uL)
                                          quint32 m_amountNeeded;          // amount needed for synth (in uL)
                                          int m_slotNumber;                // still figuring this one out
                                          QString m_name;                  // name of the reagent
                                          ReagentBottleType m_bottleType;  // bottle type.
                                        signals:
                                          void volumeChanged();
                                          void minVolumeChanged();
                                          void amountNeededChanged();
                                        };
                                        

                                        Getting this when I try to build:

                                        /home/mzimmers/git/KOL-UI/src/lib/change_consumables/reagent_manager.h:11: error: use of deleted function ‘QObject::QObject(const QObject&)’
                                        In file included from /home/mzimmers/git/KOL-UI/src/lib/change_consumables/reagent_manager.cpp:7:0:
                                        /home/mzimmers/git/KOL-UI/src/lib/change_consumables/reagent_manager.h:11:8: error: use of deleted function ‘QObject::QObject(const QObject&)’
                                         struct Bottle : private QObject {
                                                ^~~~~~
                                        

                                        Do I have to convert Bottle from a struct to a C++ class?

                                        eyllanescE kshegunovK 2 Replies Last reply
                                        0
                                        • mzimmersM mzimmers

                                          @kshegunov

                                          Trying this:

                                          struct Bottle : public QObject {
                                            Q_OBJECT
                                            Q_PROPERTY(quint32 volume MEMBER m_volume NOTIFY volumeChanged)
                                            Q_PROPERTY(quint32 minVolume MEMBER m_minVolume NOTIFY minVolumeChanged)
                                            Q_PROPERTY(quint32 amountNeeded MEMBER m_amountNeeded NOTIFY amountNeededChanged)
                                            Q_PROPERTY(int slotNumber MEMBER m_slotNumber)
                                            Q_PROPERTY(QString name MEMBER m_name)
                                            Q_PROPERTY(ReagentBottleType bottleType MEMBER m_bottleType)
                                          
                                           public:
                                            // needed to represent amounts in int, not float
                                            // because using floats causes a float-equal error
                                            // in the generated MOC file.
                                            quint32 m_volume;                // amount in bottle (in uL)
                                            quint32 m_minVolume;             // amount in bottle that can't be used (in uL)
                                            quint32 m_amountNeeded;          // amount needed for synth (in uL)
                                            int m_slotNumber;                // still figuring this one out
                                            QString m_name;                  // name of the reagent
                                            ReagentBottleType m_bottleType;  // bottle type.
                                          signals:
                                            void volumeChanged();
                                            void minVolumeChanged();
                                            void amountNeededChanged();
                                          };
                                          

                                          Getting this when I try to build:

                                          /home/mzimmers/git/KOL-UI/src/lib/change_consumables/reagent_manager.h:11: error: use of deleted function ‘QObject::QObject(const QObject&)’
                                          In file included from /home/mzimmers/git/KOL-UI/src/lib/change_consumables/reagent_manager.cpp:7:0:
                                          /home/mzimmers/git/KOL-UI/src/lib/change_consumables/reagent_manager.h:11:8: error: use of deleted function ‘QObject::QObject(const QObject&)’
                                           struct Bottle : private QObject {
                                                  ^~~~~~
                                          

                                          Do I have to convert Bottle from a struct to a C++ class?

                                          eyllanescE Offline
                                          eyllanescE Offline
                                          eyllanesc
                                          wrote on last edited by
                                          #20

                                          @mzimmers QObject is not copyable so you have to remove the copy constructor from Bottle.

                                          If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

                                          1 Reply Last reply
                                          1

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved