Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Can't get values from QList in QML
QtWS25 Last Chance

Can't get values from QList in QML

Scheduled Pinned Locked Moved Solved General and Desktop
9 Posts 2 Posters 581 Views
  • 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.
  • Atr0p0sA Offline
    Atr0p0sA Offline
    Atr0p0s
    wrote on last edited by
    #1

    Hello!
    I have my simple class that should give access to QList:

    struct ChartPoint {
        int x;
        int y;
    };
    
    class ChartPointList : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(QList<ChartPoint> list READ chartPointList /*WRITE setChartPointList*/ NOTIFY chartPointListChanged)
    
    public:
        ChartPointList(QObject* parent) : QObject(parent)
        {
            /* for test */
            m_chartPointList.append(ChartPoint{1, 1});
        } 
    QList<ChartPoint> chartPointList() const;
    signals:
        void chartPointListChanged();
    private:
        QList<ChartPoint> m_chartPointList;
    };
    

    I registered type in main.cpp:

    qmlRegisterType<ChartPointList>("com.myinc.ChartPointList", 1, 0, "ChartPointList");
    

    but I can't get values from the list.

    console.log(first.list);
    console.log(first[0].x);
    

    show

    qml: QVariant(QList<ChartPoint>, )
    qrc:/QML-graph/Main.qml:20: TypeError: Cannot read property 'x' of undefined
    

    Perhaps I should use QVariant in some way?
    Or maybe the whole approach is wrong...

    My goal is to read a file with c++ and make a list of points (x, y) from it. And then via ChartView draw these points on the chart.

    Thanks for any tips!

    J.HilkJ 1 Reply Last reply
    0
    • Atr0p0sA Atr0p0s

      Hello!
      I have my simple class that should give access to QList:

      struct ChartPoint {
          int x;
          int y;
      };
      
      class ChartPointList : public QObject
      {
          Q_OBJECT
          Q_PROPERTY(QList<ChartPoint> list READ chartPointList /*WRITE setChartPointList*/ NOTIFY chartPointListChanged)
      
      public:
          ChartPointList(QObject* parent) : QObject(parent)
          {
              /* for test */
              m_chartPointList.append(ChartPoint{1, 1});
          } 
      QList<ChartPoint> chartPointList() const;
      signals:
          void chartPointListChanged();
      private:
          QList<ChartPoint> m_chartPointList;
      };
      

      I registered type in main.cpp:

      qmlRegisterType<ChartPointList>("com.myinc.ChartPointList", 1, 0, "ChartPointList");
      

      but I can't get values from the list.

      console.log(first.list);
      console.log(first[0].x);
      

      show

      qml: QVariant(QList<ChartPoint>, )
      qrc:/QML-graph/Main.qml:20: TypeError: Cannot read property 'x' of undefined
      

      Perhaps I should use QVariant in some way?
      Or maybe the whole approach is wrong...

      My goal is to read a file with c++ and make a list of points (x, y) from it. And then via ChartView draw these points on the chart.

      Thanks for any tips!

      J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by J.Hilk
      #2

      @Atr0p0syou in your case, you need to should work with QProperties, if you want to access the data from QML:

      class ChartPoint {
          Q_GADGET
          Q_PROPERTY(int x MEMBER m_x)
          Q_PROPERTY(int y MEMBER m_y)
          
      public:
          int m_x;
          int m_y;
      };
      

      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      Atr0p0sA 1 Reply Last reply
      1
      • J.HilkJ J.Hilk

        @Atr0p0syou in your case, you need to should work with QProperties, if you want to access the data from QML:

        class ChartPoint {
            Q_GADGET
            Q_PROPERTY(int x MEMBER m_x)
            Q_PROPERTY(int y MEMBER m_y)
            
        public:
            int m_x;
            int m_y;
        };
        
        Atr0p0sA Offline
        Atr0p0sA Offline
        Atr0p0s
        wrote on last edited by Atr0p0s
        #3

        @J-Hilk Thanks, the list is now recognizable as I can see, but the point isn't:

        console.log(first.list); --- qml: [ChartPoint(1, 1)]
        console.log(first[0]); --- qml: undefined
        console.log(first[0].x); --- Cannot read property 'x' of undefined
        

        Header:

        class ChartPoint
        {
            Q_GADGET
            Q_PROPERTY(int x MEMBER m_x)
            Q_PROPERTY(int y MEMBER m_y)
        
        public:
            int m_x;
            int m_y;
        };
        
        class ChartPointList : public QObject
        {
            Q_OBJECT
            Q_PROPERTY(QList<ChartPoint> list READ chartPointList NOTIFY chartPointListChanged)
            QML_ELEMENT
        
        public:
            ChartPointList(QObject* parent = nullptr);
            QList<ChartPoint> chartPointList() const;
        
        signals:
            void chartPointListChanged();
        
        private:
            QList<ChartPoint> m_chartPointList;
        };
        

        I registered both classes:

        qmlRegisterType<ChartPoint>("com.myinc.chartPoint", 1, 0, "ChartPoint");
        qmlRegisterType<ChartPointList>("com.myinc.chartPointList", 1, 0, "ChartPointList");
        

        Also, I get the warning in the output: qt.qml.typeregistration: Invalid QML element name "ChartPoint"; value type names should begin with a lowercase letter, but if I write chartPoint instead of ChartPoint then instead of this warning I get a new one in IDE: QML types must begin with uppercase.

        Of course, I could use special functions to get x and y values such as

        int ChartPointList::valueX(int index) const
        {
            return m_chartPointList.value(index).m_x;
        }
        

        but I wish it was a little prettier.

        J.HilkJ 1 Reply Last reply
        0
        • Atr0p0sA Atr0p0s

          @J-Hilk Thanks, the list is now recognizable as I can see, but the point isn't:

          console.log(first.list); --- qml: [ChartPoint(1, 1)]
          console.log(first[0]); --- qml: undefined
          console.log(first[0].x); --- Cannot read property 'x' of undefined
          

          Header:

          class ChartPoint
          {
              Q_GADGET
              Q_PROPERTY(int x MEMBER m_x)
              Q_PROPERTY(int y MEMBER m_y)
          
          public:
              int m_x;
              int m_y;
          };
          
          class ChartPointList : public QObject
          {
              Q_OBJECT
              Q_PROPERTY(QList<ChartPoint> list READ chartPointList NOTIFY chartPointListChanged)
              QML_ELEMENT
          
          public:
              ChartPointList(QObject* parent = nullptr);
              QList<ChartPoint> chartPointList() const;
          
          signals:
              void chartPointListChanged();
          
          private:
              QList<ChartPoint> m_chartPointList;
          };
          

          I registered both classes:

          qmlRegisterType<ChartPoint>("com.myinc.chartPoint", 1, 0, "ChartPoint");
          qmlRegisterType<ChartPointList>("com.myinc.chartPointList", 1, 0, "ChartPointList");
          

          Also, I get the warning in the output: qt.qml.typeregistration: Invalid QML element name "ChartPoint"; value type names should begin with a lowercase letter, but if I write chartPoint instead of ChartPoint then instead of this warning I get a new one in IDE: QML types must begin with uppercase.

          Of course, I could use special functions to get x and y values such as

          int ChartPointList::valueX(int index) const
          {
              return m_chartPointList.value(index).m_x;
          }
          

          but I wish it was a little prettier.

          J.HilkJ Offline
          J.HilkJ Offline
          J.Hilk
          Moderators
          wrote on last edited by
          #4

          @Atr0p0s It's possible that QGadget is not enough, I thought it is but I may be wrong. Make it a proper QObject and use the Q_OBJECT macro instead


          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


          Q: What's that?
          A: It's blue light.
          Q: What does it do?
          A: It turns blue.

          Atr0p0sA 1 Reply Last reply
          1
          • J.HilkJ J.Hilk

            @Atr0p0s It's possible that QGadget is not enough, I thought it is but I may be wrong. Make it a proper QObject and use the Q_OBJECT macro instead

            Atr0p0sA Offline
            Atr0p0sA Offline
            Atr0p0s
            wrote on last edited by
            #5

            @J-Hilk Still doesn't work. Perhaps I should use a model or functions for direct access to the data?

            What I tried:

            //thing-object.h
            class Thing : public QObject
            {
                Q_OBJECT
                Q_PROPERTY (int     size READ getSize CONSTANT)
                Q_PROPERTY (QString name READ getName CONSTANT)
            
            public:
                Thing(QObject * parent = NULL) : QObject(parent) {}
            
                int     getSize () const { return m_size; }
                void    setSize (int s) { m_size = s; }
                QString getName () const { return m_name; }
                void    setName (QString n) { m_name = n; }
            
            private:
                int     m_size;
                QString m_name;
            };
            
            class ThingManager : public QObject
            {
                Q_OBJECT
                Q_PROPERTY(QList<Thing*> things READ getThings NOTIFY thingsChanged)
            
            public:
                QList<Thing*> getThings () const { return m_things; }
                void append (Thing* thg) { m_things.append(thg); }
            signals:
                void thingsChanged ();
            private:
                QList<Thing*> m_things;
            };
            
            //main.cpp
            #include "thing-object.h"
            int main(int argc, char *argv[])
            {
                QGuiApplication app(argc, argv);
            
                qmlRegisterType<Thing>("com.myinc.thing", 1, 0, "Thing");
                qmlRegisterType<ThingManager>("com.myinc.thingManager", 1, 0, "ThingManager");
            
                Thing* thg = new Thing;
                thg->setSize(5); thg->setName("Cow");
                ThingManager man;
                man.append(thg);
            
                QQmlApplicationEngine engine;
                engine.rootContext()->setContextProperty(QStringLiteral("first"), &man);
                const QUrl url(u"qrc:/testAgain/Main.qml"_qs);
                QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed,
                    &app, []() { QCoreApplication::exit(-1); },
                    Qt::QueuedConnection);
                engine.load(url);
            
                return app.exec();
            }
            
            //main.qml
            import QtQuick
            import QtQuick.Window
            import com.myinc.thing
            import com.myinc.thingManager
            import QtQuick.Controls
            
            Window {
                width: 640
                height: 480
                visible: true
                title: qsTr("Hello World")
            
                Button {
                    text: "Press"
                    onClicked: {
                        console.log(first.things);
                        console.log(first[0].size);
                    }
                }
            }
            
            J.HilkJ 1 Reply Last reply
            0
            • Atr0p0sA Atr0p0s

              @J-Hilk Still doesn't work. Perhaps I should use a model or functions for direct access to the data?

              What I tried:

              //thing-object.h
              class Thing : public QObject
              {
                  Q_OBJECT
                  Q_PROPERTY (int     size READ getSize CONSTANT)
                  Q_PROPERTY (QString name READ getName CONSTANT)
              
              public:
                  Thing(QObject * parent = NULL) : QObject(parent) {}
              
                  int     getSize () const { return m_size; }
                  void    setSize (int s) { m_size = s; }
                  QString getName () const { return m_name; }
                  void    setName (QString n) { m_name = n; }
              
              private:
                  int     m_size;
                  QString m_name;
              };
              
              class ThingManager : public QObject
              {
                  Q_OBJECT
                  Q_PROPERTY(QList<Thing*> things READ getThings NOTIFY thingsChanged)
              
              public:
                  QList<Thing*> getThings () const { return m_things; }
                  void append (Thing* thg) { m_things.append(thg); }
              signals:
                  void thingsChanged ();
              private:
                  QList<Thing*> m_things;
              };
              
              //main.cpp
              #include "thing-object.h"
              int main(int argc, char *argv[])
              {
                  QGuiApplication app(argc, argv);
              
                  qmlRegisterType<Thing>("com.myinc.thing", 1, 0, "Thing");
                  qmlRegisterType<ThingManager>("com.myinc.thingManager", 1, 0, "ThingManager");
              
                  Thing* thg = new Thing;
                  thg->setSize(5); thg->setName("Cow");
                  ThingManager man;
                  man.append(thg);
              
                  QQmlApplicationEngine engine;
                  engine.rootContext()->setContextProperty(QStringLiteral("first"), &man);
                  const QUrl url(u"qrc:/testAgain/Main.qml"_qs);
                  QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed,
                      &app, []() { QCoreApplication::exit(-1); },
                      Qt::QueuedConnection);
                  engine.load(url);
              
                  return app.exec();
              }
              
              //main.qml
              import QtQuick
              import QtQuick.Window
              import com.myinc.thing
              import com.myinc.thingManager
              import QtQuick.Controls
              
              Window {
                  width: 640
                  height: 480
                  visible: true
                  title: qsTr("Hello World")
              
                  Button {
                      text: "Press"
                      onClicked: {
                          console.log(first.things);
                          console.log(first[0].size);
                      }
                  }
              }
              
              J.HilkJ Offline
              J.HilkJ Offline
              J.Hilk
              Moderators
              wrote on last edited by
              #6

              @Atr0p0s said in Can't get values from QList in QML:

              console.log(first[0].size);

              shouldn't this be first.things[0].size ?


              Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


              Q: What's that?
              A: It's blue light.
              Q: What does it do?
              A: It turns blue.

              Atr0p0sA 1 Reply Last reply
              1
              • J.HilkJ J.Hilk

                @Atr0p0s said in Can't get values from QList in QML:

                console.log(first[0].size);

                shouldn't this be first.things[0].size ?

                Atr0p0sA Offline
                Atr0p0sA Offline
                Atr0p0s
                wrote on last edited by
                #7

                @J-Hilk I am so sorry, keep forgetting that there is no compile time error checking :(
                You are right - it works also with Q_GADGET.
                Thanks a lot!

                Could you also advise please, if qml copies the entire list to access one element?

                J.HilkJ 1 Reply Last reply
                1
                • Atr0p0sA Atr0p0s has marked this topic as solved on
                • Atr0p0sA Atr0p0s

                  @J-Hilk I am so sorry, keep forgetting that there is no compile time error checking :(
                  You are right - it works also with Q_GADGET.
                  Thanks a lot!

                  Could you also advise please, if qml copies the entire list to access one element?

                  J.HilkJ Offline
                  J.HilkJ Offline
                  J.Hilk
                  Moderators
                  wrote on last edited by J.Hilk
                  #8

                  @Atr0p0s said in Can't get values from QList in QML:

                  I am so sorry, keep forgetting that there is no compile time error checking :(
                  You are right - it works also with Q_GADGET.

                  Don't worry a pit fall I myself fall into regularly :D

                  Could you also advise please, if qml copies the entire list to access one element?

                  That I'm unsure about, sorry. I know that QObjects can't be copied, and its also kind of irrelevant, as its a list of pointers :D

                  Just make sure to handle ownership of the objects correctly or the QML will take ownership and may GC them at any moment it sees fit.


                  Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                  Q: What's that?
                  A: It's blue light.
                  Q: What does it do?
                  A: It turns blue.

                  Atr0p0sA 1 Reply Last reply
                  1
                  • J.HilkJ J.Hilk

                    @Atr0p0s said in Can't get values from QList in QML:

                    I am so sorry, keep forgetting that there is no compile time error checking :(
                    You are right - it works also with Q_GADGET.

                    Don't worry a pit fall I myself fall into regularly :D

                    Could you also advise please, if qml copies the entire list to access one element?

                    That I'm unsure about, sorry. I know that QObjects can't be copied, and its also kind of irrelevant, as its a list of pointers :D

                    Just make sure to handle ownership of the objects correctly or the QML will take ownership and may GC them at any moment it sees fit.

                    Atr0p0sA Offline
                    Atr0p0sA Offline
                    Atr0p0s
                    wrote on last edited by
                    #9

                    @J-Hilk Got it. Thanks again and have a great day :)

                    1 Reply 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