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. accessing aggregates (QVector of a struct)
Forum Updated to NodeBB v4.3 + New Features

accessing aggregates (QVector of a struct)

Scheduled Pinned Locked Moved Solved QML and Qt Quick
52 Posts 4 Posters 8.2k 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
    #20

    OK, so why doesn't this work?

        Rectangle {
            id: rack
            function getBottleName(i) {
                return changeConsumablesViewModel.getBottleListQv()[i].m_name
            }
            Bottle {
                cellText: rack.getBottleName(0)// "W7"
            }
    

    I get this error on the line with the "return" statement:

    TypeError: Cannot read property 'm_name' of undefined

    kshegunovK 1 Reply Last reply
    0
    • mzimmersM mzimmers

      OK, so why doesn't this work?

          Rectangle {
              id: rack
              function getBottleName(i) {
                  return changeConsumablesViewModel.getBottleListQv()[i].m_name
              }
              Bottle {
                  cellText: rack.getBottleName(0)// "W7"
              }
      

      I get this error on the line with the "return" statement:

      TypeError: Cannot read property 'm_name' of undefined

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

      @mzimmers said in accessing aggregates (QVector of a struct):

      TypeError: Cannot read property 'm_name' of undefined

      Your property is called name, also check the elements you get in that array. Side note: you may need to wait for the component to be fully loaded before doing that (but take with a grain of salt).

      Read and abide by the Qt Code of Conduct

      mzimmersM 1 Reply Last reply
      1
      • kshegunovK kshegunov

        @mzimmers said in accessing aggregates (QVector of a struct):

        TypeError: Cannot read property 'm_name' of undefined

        Your property is called name, also check the elements you get in that array. Side note: you may need to wait for the component to be fully loaded before doing that (but take with a grain of salt).

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

        @kshegunov said in accessing aggregates (QVector of a struct):

        @mzimmers said in accessing aggregates (QVector of a struct):

        TypeError: Cannot read property 'm_name' of undefined

        Your property is called name, also check the elements you get in that array.

        Tried with "name" -- same error.

        Side note: you may need to wait for the component to be fully loaded before doing that (but take with a grain of salt).

        Actually, I think you're on to it here. For some reason, the people who wrote this app (I'm just maintaining it) load all the QML files up-front, rather than as-needed. I think the problem is that this is an empty vector when this function is first called...I need to think of how best to handle that.

        kshegunovK 1 Reply Last reply
        0
        • mzimmersM mzimmers

          @kshegunov said in accessing aggregates (QVector of a struct):

          @mzimmers said in accessing aggregates (QVector of a struct):

          TypeError: Cannot read property 'm_name' of undefined

          Your property is called name, also check the elements you get in that array.

          Tried with "name" -- same error.

          Side note: you may need to wait for the component to be fully loaded before doing that (but take with a grain of salt).

          Actually, I think you're on to it here. For some reason, the people who wrote this app (I'm just maintaining it) load all the QML files up-front, rather than as-needed. I think the problem is that this is an empty vector when this function is first called...I need to think of how best to handle that.

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

          @mzimmers said in accessing aggregates (QVector of a struct):

          Actually, I think you're on to it here. For some reason, the people who wrote this app (I'm just maintaining it) load all the QML files up-front, rather than as-needed. I think the problem is that this is an empty vector when this function is first called...I need to think of how best to handle that.

          Check that through the console. If you want, you can try to wait for the component by adding[1]:

          Component.onCompleted: <js code to do w/e>
          

          [1]: https://doc.qt.io/qt-5/qml-qtqml-component.html#completed-signal

          Read and abide by the Qt Code of Conduct

          1 Reply Last reply
          0
          • fcarneyF Offline
            fcarneyF Offline
            fcarney
            wrote on last edited by fcarney
            #24

            Okay, I tested it. I cannot get Q_GADGET to work so I used Q_OBJECT:
            class in main.cpp:

            using ReagentBottleType = int;
            class BottleData : public QObject
            {
                Q_OBJECT
            
                Q_PROPERTY(int volume MEMBER m_volume NOTIFY somethingChanged)
                Q_PROPERTY(int amountNeeded MEMBER m_amountNeeded NOTIFY somethingChanged)
                Q_PROPERTY(int position MEMBER m_position NOTIFY somethingChanged)
                Q_PROPERTY(std::string name MEMBER m_name NOTIFY somethingChanged)
                Q_PROPERTY(ReagentBottleType bottleType MEMBER m_bottleType NOTIFY somethingChanged)
            public:
                BottleData(QObject* parent=nullptr)
                    : QObject(parent)
                {
                    connect(this, &BottleData::somethingChanged, [this](){
                        qDebug() << "somethingChanged" << m_position << QString::fromStdString(m_name) << m_volume;
                    });
                }
            
                int m_volume=0;               // amount in bottle (in uL)
                int m_amountNeeded=0;         // amount needed for synth (in uL)
                int m_position=0;                  // still figuring this one out
                std::string m_name="";              // name of the reagent
                int m_bottleType=0;  // bottle type.
            
            signals:
                void somethingChanged();
            };
            

            setting contextProperty in main.cpp for testing:

            TestObj testobj;
            auto context = engine.rootContext();
            context->setContextProperty("varlisttestobj", &testobj);
            

            QML to exercise the object in C++:

            Column {
                    anchors.top: listview1.bottom
                    Repeater {
                        model: varlisttestobj.varList
            
                        Row {
                            id: bottledelegate
            
                            width: 50
                            spacing: 20
            
                            Component.onCompleted: console.log(modelData, modelData.position, modelData.volume)
            
                            Timer {
                                interval: 1000
                                repeat: true
                                running: true
                                onTriggered: {
                                    modelData.volume += 1
                                }
                            }
            
                            Text {
                                text: modelData.position
                                height: 20
                            }
                            Text {
                                text: modelData.volume
                                height: 20
                            }
                        }
                    }
                }
            

            QML did not like uint32_t at all. So you will have to find another type that it likes on that page with compatible QML types I linked earlier.

            C++ is a perfectly valid school of magic.

            1 Reply Last reply
            1
            • fcarneyF Offline
              fcarneyF Offline
              fcarney
              wrote on last edited by
              #25

              Oops, I forgot test object in main.cpp:

              class TestObj : public QObject
              {
                  Q_OBJECT
                  Q_PROPERTY(QVariantList varList READ varList NOTIFY varListChanged)
                  //Q_PROPERTY(QObjectList objList READ objList NOTIFY objListChanged)
              
              public:
                  TestObj(QObject* parent=nullptr)
                      : QObject(parent)
                  {
                      for(int count=0; count<10; ++count){
                          auto bottle = new BottleData();
                          bottle->m_volume = count*10;
                          bottle->m_position = count;
                          m_bottleData.append(bottle);
                      }
              
                      emit varListChanged();
                  }
              
                  QVariantList varList(){
                      QVariantList list;
                      for(auto bottleData: qAsConst(m_bottleData)){
                          list.append(QVariant::fromValue(bottleData));
                      }
                      return list;
                  }
                  /*
                  QObjectList objList(){
                      QObjectList list;
                      for(auto bottleData: qAsConst(m_bottleData)){
                          list.append(bottleData);
                      }
                      return list;
                  }
                  */
              
              
              signals:
                  void varListChanged();
              
              private:
                  QVector<BottleData*> m_bottleData;
              
              };
              

              C++ is a perfectly valid school of magic.

              1 Reply Last reply
              0
              • fcarneyF Offline
                fcarneyF Offline
                fcarney
                wrote on last edited by
                #26

                I didn't expect it to trigger the somethingChanged signal in the BottleData object.

                C++ is a perfectly valid school of magic.

                1 Reply Last reply
                0
                • fcarneyF Offline
                  fcarneyF Offline
                  fcarney
                  wrote on last edited by
                  #27

                  Trying to assign to std::string didnt work either:

                  modelData.name = "fred"
                  

                  error:

                  Error: Cannot assign QString to an unregistered type
                  

                  C++ is a perfectly valid school of magic.

                  1 Reply Last reply
                  0
                  • kshegunovK Offline
                    kshegunovK Offline
                    kshegunov
                    Moderators
                    wrote on last edited by kshegunov
                    #28

                    Okay, so here you go:

                    types.h

                    #ifndef TYPES_H
                    #define TYPES_H
                    
                    #include <QObject>
                    #include <QVector>
                    #include <QVariant>
                    #include <QVariantList>
                    
                    struct Bottle
                    {
                        Q_GADGET
                    
                        Q_PROPERTY(QString name MEMBER m_name)
                        Q_PROPERTY(qreal size MEMBER m_size)
                    
                    public:
                        QString m_name;
                        qreal m_size;
                    };
                    
                    class DataSource : public QObject
                    {
                        Q_OBJECT
                    
                    public:
                        Q_INVOKABLE QVariantList getData();
                    };
                    
                    
                    #endif // TYPES_H
                    

                    main.cpp

                    #include <QGuiApplication>
                    #include <QQmlApplicationEngine>
                    #include <QQmlContext>
                    
                    #include "types.h"
                    
                    QVariantList DataSource::getData()
                    {
                        return {
                            QVariant::fromValue<Bottle>({ "First bottle", 0.75 }),
                            QVariant::fromValue<Bottle>({ "Second bottle", 0.70 })
                        };
                    }
                    
                    int main(int argc, char *argv[])
                    {
                        QGuiApplication app(argc, argv);
                    
                        QQmlApplicationEngine engine;
                        engine.addImportPath(QStringLiteral("qrc:/"));
                        QUrl url(QStringLiteral("qrc:/main.qml"));
                        QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url] (QObject * obj, const QUrl & objUrl) -> void {
                            if (!obj && url == objUrl)
                                QCoreApplication::exit(-1);
                        }, Qt::QueuedConnection);
                    
                        DataSource source;
                        engine.rootContext()->setContextProperty(QStringLiteral("DataSource"), &source);
                    
                        qmlRegisterUncreatableType<Bottle>("Example", 1, 0, "Bottle", "");
                    
                        engine.load(url);
                    
                        return app.exec();
                    }
                    

                    main.qml

                    import QtQuick 2.15
                    import QtQuick.Window 2.15
                    import QtQuick.Controls 2.15
                    
                    import Example 1.0
                    
                    Window {
                        id: mainWindow
                        visible: true
                        width: 300
                        height: 200
                        title: qsTr("Some title")
                    
                        Component {
                            id: template
                            Text {
                                text: "defaultText"
                            }
                        }
                    
                        Column {
                           Component.onCompleted: DataSource.getData().forEach(function(element) {
                               template.createObject(this, { text: element.name });
                           }, this)
                        }
                    }
                    

                    PS. QML is damn annoying ...

                    Read and abide by the Qt Code of Conduct

                    mzimmersM 1 Reply Last reply
                    1
                    • kshegunovK kshegunov

                      Okay, so here you go:

                      types.h

                      #ifndef TYPES_H
                      #define TYPES_H
                      
                      #include <QObject>
                      #include <QVector>
                      #include <QVariant>
                      #include <QVariantList>
                      
                      struct Bottle
                      {
                          Q_GADGET
                      
                          Q_PROPERTY(QString name MEMBER m_name)
                          Q_PROPERTY(qreal size MEMBER m_size)
                      
                      public:
                          QString m_name;
                          qreal m_size;
                      };
                      
                      class DataSource : public QObject
                      {
                          Q_OBJECT
                      
                      public:
                          Q_INVOKABLE QVariantList getData();
                      };
                      
                      
                      #endif // TYPES_H
                      

                      main.cpp

                      #include <QGuiApplication>
                      #include <QQmlApplicationEngine>
                      #include <QQmlContext>
                      
                      #include "types.h"
                      
                      QVariantList DataSource::getData()
                      {
                          return {
                              QVariant::fromValue<Bottle>({ "First bottle", 0.75 }),
                              QVariant::fromValue<Bottle>({ "Second bottle", 0.70 })
                          };
                      }
                      
                      int main(int argc, char *argv[])
                      {
                          QGuiApplication app(argc, argv);
                      
                          QQmlApplicationEngine engine;
                          engine.addImportPath(QStringLiteral("qrc:/"));
                          QUrl url(QStringLiteral("qrc:/main.qml"));
                          QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url] (QObject * obj, const QUrl & objUrl) -> void {
                              if (!obj && url == objUrl)
                                  QCoreApplication::exit(-1);
                          }, Qt::QueuedConnection);
                      
                          DataSource source;
                          engine.rootContext()->setContextProperty(QStringLiteral("DataSource"), &source);
                      
                          qmlRegisterUncreatableType<Bottle>("Example", 1, 0, "Bottle", "");
                      
                          engine.load(url);
                      
                          return app.exec();
                      }
                      

                      main.qml

                      import QtQuick 2.15
                      import QtQuick.Window 2.15
                      import QtQuick.Controls 2.15
                      
                      import Example 1.0
                      
                      Window {
                          id: mainWindow
                          visible: true
                          width: 300
                          height: 200
                          title: qsTr("Some title")
                      
                          Component {
                              id: template
                              Text {
                                  text: "defaultText"
                              }
                          }
                      
                          Column {
                             Component.onCompleted: DataSource.getData().forEach(function(element) {
                                 template.createObject(this, { text: element.name });
                             }, this)
                          }
                      }
                      

                      PS. QML is damn annoying ...

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

                      @kshegunov said in accessing aggregates (QVector of a struct):

                      PS. QML is damn annoying ...

                      Heh...no argument there, but if I'm reading the tea leaves correctly, it's here to stay.

                      I understand your C++ code, but I'm still trying to figure out what your QML results in. What exactly is this doing?

                      Component {
                              id: template
                              Text {
                                  text: "defaultText"
                              }
                          }
                      
                          Column {
                             Component.onCompleted: DataSource.getData().forEach(function(element) {
                                 template.createObject(this, { text: element.name });
                             }, this)
                          }
                      
                      kshegunovK 1 Reply Last reply
                      0
                      • mzimmersM mzimmers

                        @kshegunov said in accessing aggregates (QVector of a struct):

                        PS. QML is damn annoying ...

                        Heh...no argument there, but if I'm reading the tea leaves correctly, it's here to stay.

                        I understand your C++ code, but I'm still trying to figure out what your QML results in. What exactly is this doing?

                        Component {
                                id: template
                                Text {
                                    text: "defaultText"
                                }
                            }
                        
                            Column {
                               Component.onCompleted: DataSource.getData().forEach(function(element) {
                                   template.createObject(this, { text: element.name });
                               }, this)
                            }
                        
                        kshegunovK Offline
                        kshegunovK Offline
                        kshegunov
                        Moderators
                        wrote on last edited by kshegunov
                        #30

                        @mzimmers said in accessing aggregates (QVector of a struct):

                        I understand your C++ code, but I'm still trying to figure out what your QML results in. What exactly is this doing?

                        Well, I'm leveraging the fact that the QML engine is a glorified object factory. You know the widgets' basics, so with QtQuick it's the same story, more or less. It goes roughly like this:

                        1. All visual items are derived from QQuickItem, these include the stuff you see in the QML file definition like Text and Column.
                        2. Component does not(!) derive from QQuickItem, it is a QObject (or rather QQmlComponent) that's supposed to create your QQuickItems by calling QQmlComponent::createObject and passing it the correct visual parent and maybe a set of property values.
                        3. When you load a QML file, this is what the engine does - it reads and instantiates the component your file represents, hence it creates all the visual and non-visual items described in said file. It parents everything by the way the items are nested (think of it as a big QObject tree). All the visual items are (re)parented to the root QQuickItem so they get painted correctly.
                        4. After the object tree's loaded and the objects are instantiated you get the completed signal emitted and propagated through your items (visual and non-visual), so you can do w/e.
                        5. In the above code you attach to the completed signal, then you call the getData to retrieve the list of structs, then forEach of the elements of the array you execute the anonymous function. The function is a dummy mostly. It just needs to go get the reference to the template component (which isn't a visual item, as mentioned) and call it's createObject to create the Text item contained. The first argument of the method is the visual parent (which is the Column in this case) and the second parameter is the set of properties to pass along, which is just the text value retrieved from the structure.

                        PS. This code's tested (unlike most of the snippets I provide) so you can directly plug it in your project/app and play with it as you wish.

                        Read and abide by the Qt Code of Conduct

                        mzimmersM 1 Reply Last reply
                        2
                        • kshegunovK kshegunov

                          @mzimmers said in accessing aggregates (QVector of a struct):

                          I understand your C++ code, but I'm still trying to figure out what your QML results in. What exactly is this doing?

                          Well, I'm leveraging the fact that the QML engine is a glorified object factory. You know the widgets' basics, so with QtQuick it's the same story, more or less. It goes roughly like this:

                          1. All visual items are derived from QQuickItem, these include the stuff you see in the QML file definition like Text and Column.
                          2. Component does not(!) derive from QQuickItem, it is a QObject (or rather QQmlComponent) that's supposed to create your QQuickItems by calling QQmlComponent::createObject and passing it the correct visual parent and maybe a set of property values.
                          3. When you load a QML file, this is what the engine does - it reads and instantiates the component your file represents, hence it creates all the visual and non-visual items described in said file. It parents everything by the way the items are nested (think of it as a big QObject tree). All the visual items are (re)parented to the root QQuickItem so they get painted correctly.
                          4. After the object tree's loaded and the objects are instantiated you get the completed signal emitted and propagated through your items (visual and non-visual), so you can do w/e.
                          5. In the above code you attach to the completed signal, then you call the getData to retrieve the list of structs, then forEach of the elements of the array you execute the anonymous function. The function is a dummy mostly. It just needs to go get the reference to the template component (which isn't a visual item, as mentioned) and call it's createObject to create the Text item contained. The first argument of the method is the visual parent (which is the Column in this case) and the second parameter is the set of properties to pass along, which is just the text value retrieved from the structure.

                          PS. This code's tested (unlike most of the snippets I provide) so you can directly plug it in your project/app and play with it as you wish.

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

                          @kshegunov OK, I think I understand 1-4. But where is the getData() function explicitly referenced/called? (I think your getData() is the equivalent to my QVariantList BottleList::getBottleListQv().)

                          I still don't understand how to retrieve the information to use it in my bottle objects.

                                  Bottle {
                                      id: bottle1
                                      cellX: 25
                                      cellY: 105
                                      cellHeight: 75
                                      cellWidth: 75
                                      bottleScaleFactor: scaleFactor
                                      cellText: "W7" // how to replace this with something from getData()?
                                      cellColor: "red"
                                  }
                          

                          Thanks...

                          ODБOïO kshegunovK 2 Replies Last reply
                          0
                          • mzimmersM mzimmers

                            @kshegunov OK, I think I understand 1-4. But where is the getData() function explicitly referenced/called? (I think your getData() is the equivalent to my QVariantList BottleList::getBottleListQv().)

                            I still don't understand how to retrieve the information to use it in my bottle objects.

                                    Bottle {
                                        id: bottle1
                                        cellX: 25
                                        cellY: 105
                                        cellHeight: 75
                                        cellWidth: 75
                                        bottleScaleFactor: scaleFactor
                                        cellText: "W7" // how to replace this with something from getData()?
                                        cellColor: "red"
                                    }
                            

                            Thanks...

                            ODБOïO Offline
                            ODБOïO Offline
                            ODБOï
                            wrote on last edited by
                            #32

                            hi

                            @mzimmers said in accessing aggregates (QVector of a struct):

                            I still don't understand how to retrieve the information to use it in my bottle objects.

                            the answer is

                            @kshegunov said in accessing aggregates (QVector of a struct):

                            In the above code you attach to the completed signal, then you call the getData to retrieve the list of structs, then forEach of the elements of the array you execute the anonymous function. The function is a dummy mostly. It just needs to go get the reference to the template component (which isn't a visual item, as mentioned) and call it's createObject to create the Text item contained. The first argument of the method is the visual parent (which is the Column in this case) and the second parameter is the set of properties to pass along, which is just the text value retrieved from the structure.

                             Column {
                                   Component.onCompleted: 
                                
                                    DataSource.getData().forEach(function(element) {//anonymous  function call for each object  returned by  getData()
                                     
                                       template.createObject(this, { text: element.name }); // create a qml object  using the template and pass  the value retrieved from the structure  ( text:element.name )
                                   }, this)
                                }
                            

                            Please make an empty project and test one of the examples given by @kshegunov @fcarney or me

                            mzimmersM 1 Reply Last reply
                            0
                            • ODБOïO ODБOï

                              hi

                              @mzimmers said in accessing aggregates (QVector of a struct):

                              I still don't understand how to retrieve the information to use it in my bottle objects.

                              the answer is

                              @kshegunov said in accessing aggregates (QVector of a struct):

                              In the above code you attach to the completed signal, then you call the getData to retrieve the list of structs, then forEach of the elements of the array you execute the anonymous function. The function is a dummy mostly. It just needs to go get the reference to the template component (which isn't a visual item, as mentioned) and call it's createObject to create the Text item contained. The first argument of the method is the visual parent (which is the Column in this case) and the second parameter is the set of properties to pass along, which is just the text value retrieved from the structure.

                               Column {
                                     Component.onCompleted: 
                                  
                                      DataSource.getData().forEach(function(element) {//anonymous  function call for each object  returned by  getData()
                                       
                                         template.createObject(this, { text: element.name }); // create a qml object  using the template and pass  the value retrieved from the structure  ( text:element.name )
                                     }, this)
                                  }
                              

                              Please make an empty project and test one of the examples given by @kshegunov @fcarney or me

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

                              @LeLev (et al): kshugenov's example does indeed work. I tried modifying it as follows:

                                  Column {
                                     property var myArray: []
                                     Component.onCompleted: DataSource.getData().forEach(function(bottle) {
                              //           template.createObject(this, { text: bottle.name });
                                         myArray.push(bottle.name)
                                     }, this)
                                  Text {
                                      text: myArray[0]
                                  }
                              

                              But I get a runtime error that myArray is not defined. Am I supposed to use something other than a property var for this?

                              Thanks...

                              ODБOïO 1 Reply Last reply
                              0
                              • mzimmersM mzimmers

                                @LeLev (et al): kshugenov's example does indeed work. I tried modifying it as follows:

                                    Column {
                                       property var myArray: []
                                       Component.onCompleted: DataSource.getData().forEach(function(bottle) {
                                //           template.createObject(this, { text: bottle.name });
                                           myArray.push(bottle.name)
                                       }, this)
                                    Text {
                                        text: myArray[0]
                                    }
                                

                                But I get a runtime error that myArray is not defined. Am I supposed to use something other than a property var for this?

                                Thanks...

                                ODБOïO Offline
                                ODБOïO Offline
                                ODБOï
                                wrote on last edited by ODБOï
                                #34

                                @mzimmers said in accessing aggregates (QVector of a struct):

                                myArray is not defined

                                you need to assign the id of Column so you can access its properties from outside, it is qml basics

                                Column {
                                id :col
                                property var myArray: []
                                Text {
                                text: col.myArray[0]
                                }
                                }

                                @mzimmers said in accessing aggregates (QVector of a struct):

                                kshugenov's example does indeed work.

                                it does almost exactly the same thing as my very first example/answer.

                                mzimmersM 1 Reply Last reply
                                1
                                • ODБOïO ODБOï

                                  @mzimmers said in accessing aggregates (QVector of a struct):

                                  myArray is not defined

                                  you need to assign the id of Column so you can access its properties from outside, it is qml basics

                                  Column {
                                  id :col
                                  property var myArray: []
                                  Text {
                                  text: col.myArray[0]
                                  }
                                  }

                                  @mzimmers said in accessing aggregates (QVector of a struct):

                                  kshugenov's example does indeed work.

                                  it does almost exactly the same thing as my very first example/answer.

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

                                  @LeLev ah. So, now my code looks like this:

                                      Column {
                                          id: myColumn
                                          property var myArray: []
                                          Component.onCompleted: DataSource.getData().forEach(function(bottle) {
                                              //           template.createObject(this, { text: bottle.name });
                                              myArray.push(bottle.name)
                                          }, this)
                                          Text {
                                              text: myColumn.myArray[0]
                                          }
                                          Text {
                                              text:myColumn.myArray[1]
                                          }
                                          Text {
                                              text: myColumn.myArray[2]
                                          }
                                      }
                                  

                                  and I'm getting this error: "Unable to assign [undefined] to QString"

                                  EDIT: I've stepped through this in the debugger, and the array is most definitely being created.

                                  ODБOïO 1 Reply Last reply
                                  1
                                  • mzimmersM mzimmers

                                    @LeLev ah. So, now my code looks like this:

                                        Column {
                                            id: myColumn
                                            property var myArray: []
                                            Component.onCompleted: DataSource.getData().forEach(function(bottle) {
                                                //           template.createObject(this, { text: bottle.name });
                                                myArray.push(bottle.name)
                                            }, this)
                                            Text {
                                                text: myColumn.myArray[0]
                                            }
                                            Text {
                                                text:myColumn.myArray[1]
                                            }
                                            Text {
                                                text: myColumn.myArray[2]
                                            }
                                        }
                                    

                                    and I'm getting this error: "Unable to assign [undefined] to QString"

                                    EDIT: I've stepped through this in the debugger, and the array is most definitely being created.

                                    ODБOïO Offline
                                    ODБOïO Offline
                                    ODБOï
                                    wrote on last edited by ODБOï
                                    #36

                                    @mzimmers said in accessing aggregates (QVector of a struct):

                                    Column {
                                    id: myColumn
                                    property var myArray: []
                                    Component.onCompleted: DataSource.getData().forEach(function(bottle) {
                                    // template.createObject(this, { text: bottle.name });
                                    myArray.push(bottle.name)
                                    }, this)

                                    you should not modify myArray directly in the function but create a local array then copy its content into myArray

                                    Column {
                                            id: myColumn
                                            property var myArray: []
                                            Component.onCompleted: {
                                               var arr = []
                                               DataSource.getData().forEach(function(bottle) {           
                                                //myArray.push(bottle.name)
                                                  arr.push(bottle.name)
                                            }, this);
                                          myColumn.myArray = arr;          
                                    }
                                    
                                    mzimmersM 1 Reply Last reply
                                    3
                                    • ODБOïO ODБOï

                                      @mzimmers said in accessing aggregates (QVector of a struct):

                                      Column {
                                      id: myColumn
                                      property var myArray: []
                                      Component.onCompleted: DataSource.getData().forEach(function(bottle) {
                                      // template.createObject(this, { text: bottle.name });
                                      myArray.push(bottle.name)
                                      }, this)

                                      you should not modify myArray directly in the function but create a local array then copy its content into myArray

                                      Column {
                                              id: myColumn
                                              property var myArray: []
                                              Component.onCompleted: {
                                                 var arr = []
                                                 DataSource.getData().forEach(function(bottle) {           
                                                  //myArray.push(bottle.name)
                                                    arr.push(bottle.name)
                                              }, this);
                                            myColumn.myArray = arr;          
                                      }
                                      
                                      mzimmersM Offline
                                      mzimmersM Offline
                                      mzimmers
                                      wrote on last edited by
                                      #37

                                      @LeLev that works! Thanks for your patience on this.

                                      May I ask why my approach didn't work?

                                      ODБOïO 1 Reply Last reply
                                      0
                                      • mzimmersM mzimmers

                                        @LeLev that works! Thanks for your patience on this.

                                        May I ask why my approach didn't work?

                                        ODБOïO Offline
                                        ODБOïO Offline
                                        ODБOï
                                        wrote on last edited by ODБOï
                                        #38

                                        @mzimmers
                                        here is an example to illustrate, uncomment one or the other Component.onCompleted, you will observe that when we call
                                        col.myArr.push("N° " + i) directly, the view is empty at the beginning but myArr actually contains the items

                                        Window {
                                            width: 640
                                            height: 480
                                            visible: true
                                        
                                            Column{
                                                id:col
                                                property var myArr : []
                                        
                                        // calling myArr.push() directly in the function.
                                        //   You will need to somehow "refresh" the view, (in this example see the button that resets the repeater model)
                                                
                                        //        Component.onCompleted: {
                                        //            var arr = []
                                        //            for(var i=0;i<10;i++){
                                        //                col.myArr.push("N° " + i)
                                        //            }
                                        //        }
                                        //OR ------------------------------------------
                                        // creating a local array        
                                                
                                        //        Component.onCompleted: {
                                        //            var arr = []
                                        //            for(var i=0;i<10;i++){
                                        //                arr.push("N° " + i)
                                        //            }
                                        //            col.myArr = arr;
                                        //        }
                                        
                                                //--------------------------------------------------
                                                Repeater{
                                                    id:rep
                                                    model: col.myArr.length
                                        
                                                    Text {
                                                        id: txt
                                                        text: col.myArr[index]
                                                    }
                                                }
                                                //--------------------------------------------------
                                                Button{ 
                                                    text: 'refresh'
                                                    onClicked:{ rep.model = 0; rep.model = col.myArr.length;  console.log(col.myArr) } // just to reset the repeater
                                                }
                                            }
                                        }
                                        

                                        It's great that your solution worked but why not implement something where you can simply write

                                         Text {
                                                    text: DataSource.getDataByIndex(0).name 
                                                }
                                        
                                        mzimmersM 1 Reply Last reply
                                        0
                                        • ODБOïO ODБOï

                                          @mzimmers
                                          here is an example to illustrate, uncomment one or the other Component.onCompleted, you will observe that when we call
                                          col.myArr.push("N° " + i) directly, the view is empty at the beginning but myArr actually contains the items

                                          Window {
                                              width: 640
                                              height: 480
                                              visible: true
                                          
                                              Column{
                                                  id:col
                                                  property var myArr : []
                                          
                                          // calling myArr.push() directly in the function.
                                          //   You will need to somehow "refresh" the view, (in this example see the button that resets the repeater model)
                                                  
                                          //        Component.onCompleted: {
                                          //            var arr = []
                                          //            for(var i=0;i<10;i++){
                                          //                col.myArr.push("N° " + i)
                                          //            }
                                          //        }
                                          //OR ------------------------------------------
                                          // creating a local array        
                                                  
                                          //        Component.onCompleted: {
                                          //            var arr = []
                                          //            for(var i=0;i<10;i++){
                                          //                arr.push("N° " + i)
                                          //            }
                                          //            col.myArr = arr;
                                          //        }
                                          
                                                  //--------------------------------------------------
                                                  Repeater{
                                                      id:rep
                                                      model: col.myArr.length
                                          
                                                      Text {
                                                          id: txt
                                                          text: col.myArr[index]
                                                      }
                                                  }
                                                  //--------------------------------------------------
                                                  Button{ 
                                                      text: 'refresh'
                                                      onClicked:{ rep.model = 0; rep.model = col.myArr.length;  console.log(col.myArr) } // just to reset the repeater
                                                  }
                                              }
                                          }
                                          

                                          It's great that your solution worked but why not implement something where you can simply write

                                           Text {
                                                      text: DataSource.getDataByIndex(0).name 
                                                  }
                                          
                                          mzimmersM Offline
                                          mzimmersM Offline
                                          mzimmers
                                          wrote on last edited by
                                          #39

                                          @LeLev I may have spoken a bit too soon...when I try to apply this from the example to my application, I get the error again.

                                          Column {
                                          	id: myColumn
                                          	property var myArray: []
                                          	Component.onCompleted: {
                                          		var arr = []
                                          		BottleList.getBottleListQv().forEach(function(bottle) {
                                          			arr.push(bottle.name)
                                          		}, this);
                                          		myColumn.myArray = arr;
                                          	}
                                          
                                          	Bottle {
                                          		cellText: myColumn.myArray[0]//"W7"
                                          	}
                                          

                                          The array element notation seems like it's correct; can you see what I'm doing wrong?

                                          Regarding writing a function for the name: I would do that, and I still may, but I want to grow this to return several values in the struct: name, position, capacity, fill level, etc. So far, this approach looks better for that.

                                          ODБOïO kshegunovK 2 Replies Last reply
                                          0

                                          • Login

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