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. Best way to access a cpp structure in QML
QtWS25 Last Chance

Best way to access a cpp structure in QML

Scheduled Pinned Locked Moved Solved QML and Qt Quick
qmlqtquickqtquick2qvariant
19 Posts 6 Posters 19.8k 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.
  • ? Offline
    ? Offline
    A Former User
    wrote on last edited by A Former User
    #3

    Hi! Simple answer is: no. To make the members' names available to QML your object has to derive from QObject and expose the members via Q_PROPERTY. If, for some reason, you need to keep the struct as it is, you'll need to provide a wrapper class as an interface to QML, like:

    #ifndef MYWRAPPER_H
    #define MYWRAPPER_H
    
    #include <QObject>
    
    class MyStruct;
    
    class MyWrapper : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(int val READ val WRITE setVal NOTIFY valChanged)
        // ...
    
    public:
        explicit MyWrapper(QObject *parent = nullptr);
        ~MyWrapper();
    
        int val() const;
        void setVal(int v);
        // ...
    
    signals:
        valChanged(int);
        // ...
    
    private:
        MyStruct *m_myStruct;
    };
    
    #endif // MYWRAPPER_H
    

    A QVariant with a POD inside does not expose its members' names to the QML environment. If you want to go with QVariant and have names you need to use QVariantMap. Here is a class "Car" that exposes your MyStruct as a QVariantMap:

    car.h

    #ifndef CAR_H
    #define CAR_H
    
    #include <QObject>
    #include <QVariantMap>
    #include "mystruct.h"
    
    class Car : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(QVariantMap myStruct READ getMyStruct WRITE setMyStruct NOTIFY myStructChanged)
    
    public:
        Car(QObject *parent = nullptr);
    
        QVariantMap getMyStruct() const;
        void setMyStruct(QVariantMap myStruct);
    
    signals:
        void myStructChanged(QVariantMap myStruct);
    
    private:
        MyStruct m_myStruct;
    };
    
    #endif // CAR_H
    

    car.cpp

    #include "car.h"
    #include "myadapter.h"
    
    Car::Car(QObject *parent)
        : QObject(parent)
    {
    }
    
    QVariantMap Car::getMyStruct() const
    {
        return myStructToQVariantMap(m_myStruct);
    }
    
    void Car::setMyStruct(QVariantMap myStruct)
    {
        MyStruct newValue = myStructFromQVariantMap(myStruct);
        if (myStructEqual(m_myStruct, newValue))
            return;
        m_myStruct = newValue;
        emit myStructChanged(myStruct);
    }
    

    It relies on some helper functions:
    myadapter.h

    #ifndef MYADAPTER_H
    #define MYADAPTER_H
    
    #include "mystruct.h"
    #include <QVariantMap>
    
    QVariantMap myStructToQVariantMap(MyStruct const &myStruct);
    MyStruct myStructFromQVariantMap(QVariantMap const &vm);
    bool myStructEqual(MyStruct const &myStruct1, MyStruct const &myStruct2);
    
    #endif // MYADAPTER_H
    

    myadapter.cpp

    #include "myadapter.h"
    
    QVariantMap myStructToQVariantMap(const MyStruct &myStruct)
    {
        QVariantMap res;
        res.insert("val", myStruct.val);
        res.insert("name1", myStruct.name1);
        res.insert("name2", myStruct.name2);
        res.insert("name3", myStruct.name3);
        res.insert("name4", myStruct.name4);
        return res;
    }
    
    MyStruct myStructFromQVariantMap(const QVariantMap &vm)
    {
        MyStruct res;
        res.val = vm.value("val").toInt();
        res.name1 = vm.value("name1").toString();
        res.name2 = vm.value("name2").toString();
        res.name3 = vm.value("name3").toString();
        res.name4 = vm.value("name4").toString();
        return res;
    }
    
    bool myStructEqual(MyStruct const &myStruct1, MyStruct const &myStruct2)
    {
        if (myStruct1.val != myStruct2.val) return false;
        if (myStruct1.name1 != myStruct2.name1) return false;
        if (myStruct1.name2 != myStruct2.name2) return false;
        if (myStruct1.name3 != myStruct2.name3) return false;
        if (myStruct1.name4 != myStruct2.name4) return false;
        return true;
    }
    

    As you can see, this QVariantMap approach is pretty cumbersome and obviously involves a lot of copying. But at least you can now access "the members" by their names in QML and you get the notifications when the MyStruct object changes.

        Forum.Car {
            id: myCar
        }
    
        Row {
            anchors.centerIn: parent
            spacing: 20
    
            Button {
                text: "click me"
                onClicked: {
                    var obj = myCar.myStruct // retrieve a copy of the struct
                    obj.val = 42 // set value in the copy
                    myCar.myStruct = obj // replace old struct with the copy
                }
            }
    
            Label {
                text: myCar.myStruct.val
            }
        }
    
    P 1 Reply Last reply
    4
    • timdayT timday

      If your struct really is just 5 QStrings, personally I'd just use a QStringList (which I believe QVariant supports nicely) to communicate its state into (and from) the QML/Javascript domain.

      ? Offline
      ? Offline
      A Former User
      wrote on last edited by
      #4

      @timday QStringList is directly supported by QML, no need to go through QVariant.

      P 1 Reply Last reply
      3
      • ? A Former User

        @timday QStringList is directly supported by QML, no need to go through QVariant.

        P Offline
        P Offline
        Praveen_2017
        wrote on last edited by Praveen_2017
        #5
        This post is deleted!
        1 Reply Last reply
        0
        • ? A Former User

          Hi! Simple answer is: no. To make the members' names available to QML your object has to derive from QObject and expose the members via Q_PROPERTY. If, for some reason, you need to keep the struct as it is, you'll need to provide a wrapper class as an interface to QML, like:

          #ifndef MYWRAPPER_H
          #define MYWRAPPER_H
          
          #include <QObject>
          
          class MyStruct;
          
          class MyWrapper : public QObject
          {
              Q_OBJECT
              Q_PROPERTY(int val READ val WRITE setVal NOTIFY valChanged)
              // ...
          
          public:
              explicit MyWrapper(QObject *parent = nullptr);
              ~MyWrapper();
          
              int val() const;
              void setVal(int v);
              // ...
          
          signals:
              valChanged(int);
              // ...
          
          private:
              MyStruct *m_myStruct;
          };
          
          #endif // MYWRAPPER_H
          

          A QVariant with a POD inside does not expose its members' names to the QML environment. If you want to go with QVariant and have names you need to use QVariantMap. Here is a class "Car" that exposes your MyStruct as a QVariantMap:

          car.h

          #ifndef CAR_H
          #define CAR_H
          
          #include <QObject>
          #include <QVariantMap>
          #include "mystruct.h"
          
          class Car : public QObject
          {
              Q_OBJECT
              Q_PROPERTY(QVariantMap myStruct READ getMyStruct WRITE setMyStruct NOTIFY myStructChanged)
          
          public:
              Car(QObject *parent = nullptr);
          
              QVariantMap getMyStruct() const;
              void setMyStruct(QVariantMap myStruct);
          
          signals:
              void myStructChanged(QVariantMap myStruct);
          
          private:
              MyStruct m_myStruct;
          };
          
          #endif // CAR_H
          

          car.cpp

          #include "car.h"
          #include "myadapter.h"
          
          Car::Car(QObject *parent)
              : QObject(parent)
          {
          }
          
          QVariantMap Car::getMyStruct() const
          {
              return myStructToQVariantMap(m_myStruct);
          }
          
          void Car::setMyStruct(QVariantMap myStruct)
          {
              MyStruct newValue = myStructFromQVariantMap(myStruct);
              if (myStructEqual(m_myStruct, newValue))
                  return;
              m_myStruct = newValue;
              emit myStructChanged(myStruct);
          }
          

          It relies on some helper functions:
          myadapter.h

          #ifndef MYADAPTER_H
          #define MYADAPTER_H
          
          #include "mystruct.h"
          #include <QVariantMap>
          
          QVariantMap myStructToQVariantMap(MyStruct const &myStruct);
          MyStruct myStructFromQVariantMap(QVariantMap const &vm);
          bool myStructEqual(MyStruct const &myStruct1, MyStruct const &myStruct2);
          
          #endif // MYADAPTER_H
          

          myadapter.cpp

          #include "myadapter.h"
          
          QVariantMap myStructToQVariantMap(const MyStruct &myStruct)
          {
              QVariantMap res;
              res.insert("val", myStruct.val);
              res.insert("name1", myStruct.name1);
              res.insert("name2", myStruct.name2);
              res.insert("name3", myStruct.name3);
              res.insert("name4", myStruct.name4);
              return res;
          }
          
          MyStruct myStructFromQVariantMap(const QVariantMap &vm)
          {
              MyStruct res;
              res.val = vm.value("val").toInt();
              res.name1 = vm.value("name1").toString();
              res.name2 = vm.value("name2").toString();
              res.name3 = vm.value("name3").toString();
              res.name4 = vm.value("name4").toString();
              return res;
          }
          
          bool myStructEqual(MyStruct const &myStruct1, MyStruct const &myStruct2)
          {
              if (myStruct1.val != myStruct2.val) return false;
              if (myStruct1.name1 != myStruct2.name1) return false;
              if (myStruct1.name2 != myStruct2.name2) return false;
              if (myStruct1.name3 != myStruct2.name3) return false;
              if (myStruct1.name4 != myStruct2.name4) return false;
              return true;
          }
          

          As you can see, this QVariantMap approach is pretty cumbersome and obviously involves a lot of copying. But at least you can now access "the members" by their names in QML and you get the notifications when the MyStruct object changes.

              Forum.Car {
                  id: myCar
              }
          
              Row {
                  anchors.centerIn: parent
                  spacing: 20
          
                  Button {
                      text: "click me"
                      onClicked: {
                          var obj = myCar.myStruct // retrieve a copy of the struct
                          obj.val = 42 // set value in the copy
                          myCar.myStruct = obj // replace old struct with the copy
                      }
                  }
          
                  Label {
                      text: myCar.myStruct.val
                  }
              }
          
          P Offline
          P Offline
          pra7
          wrote on last edited by
          #6

          @Wieland Thanks!!! for your suggestion after lot of reading and searching I got the answer ,Actually we can use structs or any object which is not derived from QObject by using Q_GADGET :

          struct MyStruct {
              Q_GADGET
              int m_val;
              QString m_name1;
              QString m_name2;
              QString m_name3;
              QString m_name4;
              Q_PROPERTY(int val MEMBER m_val)
              Q_PROPERTY(QString name1 MEMBER m_name1)
              Q_PROPERTY(QString name2 MEMBER m_name2)
              Q_PROPERTY(QString name3 MEMBER m_name3)
              Q_PROPERTY(QString name4 MEMBER m_name4)
          };
          

          Then in my class i just replaced QVariant as below :

          class MyClass:public QObject
          {
              Q_OBJECT
              Q_PROPERTY(MyStruct mystr READ getMyStruct
                          WRITE setMyStruct NOTIFY myStructChanged)
          
          public:
              explicit MyClass(QObject *parent = nullptr);
              MyStruct strObj;
          
               // Edit: changed get function
               MyStruct getMyStruct() const
               {
                   return strObj;
               }
          
          // Edit: Added set function
               void setMyStruct(myStruct val)
                  {
                      mystr = val;
                      emit myStructChanged();
                  }
          signals:
          void myStructChanged();
          
          }
          

          Now in QML file i can just use classObj.mystr.name1 to access the members and i can just use classObj.mystr.name1 = "abc" to set the values.

          ? S 2 Replies Last reply
          4
          • P pra7

            @Wieland Thanks!!! for your suggestion after lot of reading and searching I got the answer ,Actually we can use structs or any object which is not derived from QObject by using Q_GADGET :

            struct MyStruct {
                Q_GADGET
                int m_val;
                QString m_name1;
                QString m_name2;
                QString m_name3;
                QString m_name4;
                Q_PROPERTY(int val MEMBER m_val)
                Q_PROPERTY(QString name1 MEMBER m_name1)
                Q_PROPERTY(QString name2 MEMBER m_name2)
                Q_PROPERTY(QString name3 MEMBER m_name3)
                Q_PROPERTY(QString name4 MEMBER m_name4)
            };
            

            Then in my class i just replaced QVariant as below :

            class MyClass:public QObject
            {
                Q_OBJECT
                Q_PROPERTY(MyStruct mystr READ getMyStruct
                            WRITE setMyStruct NOTIFY myStructChanged)
            
            public:
                explicit MyClass(QObject *parent = nullptr);
                MyStruct strObj;
            
                 // Edit: changed get function
                 MyStruct getMyStruct() const
                 {
                     return strObj;
                 }
            
            // Edit: Added set function
                 void setMyStruct(myStruct val)
                    {
                        mystr = val;
                        emit myStructChanged();
                    }
            signals:
            void myStructChanged();
            
            }
            

            Now in QML file i can just use classObj.mystr.name1 to access the members and i can just use classObj.mystr.name1 = "abc" to set the values.

            ? Offline
            ? Offline
            A Former User
            wrote on last edited by
            #7

            @pra7 Yes, that's possible, too. Just note that with that solution, MyStruct won't send notifications when a member changes. This is how basic QML types (e.g. color) are implemented.

            1 Reply Last reply
            3
            • ? Offline
              ? Offline
              A Former User
              wrote on last edited by A Former User
              #8

              One more thing, you did this...

              struct MyStruct {
                  Q_GADGET 
                  int m_val;
                  QString m_name1;
                  QString m_name2;
                  QString m_name3;
                  QString m_name4;
                  Q_PROPERTY(int val MEMBER m_val)
                  Q_PROPERTY(QString name1 MEMBER m_name1)
                  Q_PROPERTY(QString name2 MEMBER m_name2)
                  Q_PROPERTY(QString name3 MEMBER m_name3)
                  Q_PROPERTY(QString name4 MEMBER m_name4)
              };
              

              ... where you put Q_GADGET in the public section. This has the side effect that all the members that come after Q_GADGET are private now. That's because Q_GADGET is a macro that expands to...

              #define Q_GADGET \
              public: \
                  static const QMetaObject staticMetaObject; \
                  void qt_check_for_QGADGET_macro(); \
                  typedef void QtGadgetHelper; \
              private: \
                  QT_WARNING_PUSH \
                  Q_OBJECT_NO_ATTRIBUTES_WARNING \
                  Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \
                  QT_WARNING_POP \
                  QT_ANNOTATE_CLASS(qt_qgadget, "") \
                  /*end*/
              

              ... , see qobjectdefs.h.

              So maybe better follow the usual convention to avoid surprises:

              class MyStruct {
                  Q_GADGET 
                  Q_PROPERTY(int val MEMBER m_val)
                  Q_PROPERTY(QString name1 MEMBER m_name1)
                  Q_PROPERTY(QString name2 MEMBER m_name2)
                  Q_PROPERTY(QString name3 MEMBER m_name3)
                  Q_PROPERTY(QString name4 MEMBER m_name4)
              public:
                  int m_val;
                  QString m_name1;
                  QString m_name2;
                  QString m_name3;
                  QString m_name4;
              };
              
              P 2 Replies Last reply
              6
              • ? A Former User

                One more thing, you did this...

                struct MyStruct {
                    Q_GADGET 
                    int m_val;
                    QString m_name1;
                    QString m_name2;
                    QString m_name3;
                    QString m_name4;
                    Q_PROPERTY(int val MEMBER m_val)
                    Q_PROPERTY(QString name1 MEMBER m_name1)
                    Q_PROPERTY(QString name2 MEMBER m_name2)
                    Q_PROPERTY(QString name3 MEMBER m_name3)
                    Q_PROPERTY(QString name4 MEMBER m_name4)
                };
                

                ... where you put Q_GADGET in the public section. This has the side effect that all the members that come after Q_GADGET are private now. That's because Q_GADGET is a macro that expands to...

                #define Q_GADGET \
                public: \
                    static const QMetaObject staticMetaObject; \
                    void qt_check_for_QGADGET_macro(); \
                    typedef void QtGadgetHelper; \
                private: \
                    QT_WARNING_PUSH \
                    Q_OBJECT_NO_ATTRIBUTES_WARNING \
                    Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \
                    QT_WARNING_POP \
                    QT_ANNOTATE_CLASS(qt_qgadget, "") \
                    /*end*/
                

                ... , see qobjectdefs.h.

                So maybe better follow the usual convention to avoid surprises:

                class MyStruct {
                    Q_GADGET 
                    Q_PROPERTY(int val MEMBER m_val)
                    Q_PROPERTY(QString name1 MEMBER m_name1)
                    Q_PROPERTY(QString name2 MEMBER m_name2)
                    Q_PROPERTY(QString name3 MEMBER m_name3)
                    Q_PROPERTY(QString name4 MEMBER m_name4)
                public:
                    int m_val;
                    QString m_name1;
                    QString m_name2;
                    QString m_name3;
                    QString m_name4;
                };
                
                P Offline
                P Offline
                pra7
                wrote on last edited by
                #9

                @Wieland Thanks !! for pointing that .

                1 Reply Last reply
                1
                • ? A Former User

                  One more thing, you did this...

                  struct MyStruct {
                      Q_GADGET 
                      int m_val;
                      QString m_name1;
                      QString m_name2;
                      QString m_name3;
                      QString m_name4;
                      Q_PROPERTY(int val MEMBER m_val)
                      Q_PROPERTY(QString name1 MEMBER m_name1)
                      Q_PROPERTY(QString name2 MEMBER m_name2)
                      Q_PROPERTY(QString name3 MEMBER m_name3)
                      Q_PROPERTY(QString name4 MEMBER m_name4)
                  };
                  

                  ... where you put Q_GADGET in the public section. This has the side effect that all the members that come after Q_GADGET are private now. That's because Q_GADGET is a macro that expands to...

                  #define Q_GADGET \
                  public: \
                      static const QMetaObject staticMetaObject; \
                      void qt_check_for_QGADGET_macro(); \
                      typedef void QtGadgetHelper; \
                  private: \
                      QT_WARNING_PUSH \
                      Q_OBJECT_NO_ATTRIBUTES_WARNING \
                      Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \
                      QT_WARNING_POP \
                      QT_ANNOTATE_CLASS(qt_qgadget, "") \
                      /*end*/
                  

                  ... , see qobjectdefs.h.

                  So maybe better follow the usual convention to avoid surprises:

                  class MyStruct {
                      Q_GADGET 
                      Q_PROPERTY(int val MEMBER m_val)
                      Q_PROPERTY(QString name1 MEMBER m_name1)
                      Q_PROPERTY(QString name2 MEMBER m_name2)
                      Q_PROPERTY(QString name3 MEMBER m_name3)
                      Q_PROPERTY(QString name4 MEMBER m_name4)
                  public:
                      int m_val;
                      QString m_name1;
                      QString m_name2;
                      QString m_name3;
                      QString m_name4;
                  };
                  
                  P Offline
                  P Offline
                  pra7
                  wrote on last edited by
                  #10

                  @Wieland Is there any possibility that I can access structure inside a structure?

                  struct MyStruct {
                  Q_GADGET
                  int m_val;
                  QString m_name1;
                  QString m_name2;
                  QString m_name3;
                  QString m_name4;
                  MyNewStruct m_newStr; //** new Struct includes Q_GADGET macro and member definations. 
                  
                  Q_PROPERTY(int val MEMBER m_val)
                  Q_PROPERTY(QString name1 MEMBER m_name1)
                  Q_PROPERTY(QString name2 MEMBER m_name2)
                  Q_PROPERTY(QString name3 MEMBER m_name3)
                  Q_PROPERTY(QString name4 MEMBER m_name4)
                  
                  Q_PROPERTY(MyNewStruct newStr MEMBER m_newStr) //**Currently getting error 
                  };
                  
                  M 1 Reply Last reply
                  0
                  • ? Offline
                    ? Offline
                    A Former User
                    wrote on last edited by
                    #11

                    @pra7 said in Best way to access a cpp structure in QML:

                    //**Currently getting error

                    What error?

                    P P 2 Replies Last reply
                    0
                    • ? A Former User

                      @pra7 said in Best way to access a cpp structure in QML:

                      //**Currently getting error

                      What error?

                      P Offline
                      P Offline
                      Praveen_2017
                      wrote on last edited by
                      #12
                      This post is deleted!
                      1 Reply Last reply
                      0
                      • ? A Former User

                        @pra7 said in Best way to access a cpp structure in QML:

                        //**Currently getting error

                        What error?

                        P Offline
                        P Offline
                        pra7
                        wrote on last edited by
                        #13

                        @Wieland

                        error: no match for 'operator!=' (operand types are 'myStruct1' and 'myStruct1') if (_t->mynewstr != *reinterpret_cast< myStruct1*>(_v)) {
                        

                        where Mystruct1 is myNewStruct and the error is in MOC ...

                        1 Reply Last reply
                        0
                        • ? Offline
                          ? Offline
                          A Former User
                          wrote on last edited by
                          #14

                          The MOC generates some code for you to implement all the Gadget / Property stuff. Looks like the generated code uses the != operator for MyStruct. So you need to implement that:

                          public:
                              bool operator==(MyStruct const &other) const;
                              bool operator!=(MyStruct const &other) const;
                          
                          bool MyStruct::operator==(const MyStruct &other) const
                          {
                              // compare members 
                              return true;
                          }
                          
                          bool MyStruct::operator!=(MyStruct const &other) const
                          {
                              return !(*this == other);
                          }
                          
                          P 1 Reply Last reply
                          3
                          • ? A Former User

                            The MOC generates some code for you to implement all the Gadget / Property stuff. Looks like the generated code uses the != operator for MyStruct. So you need to implement that:

                            public:
                                bool operator==(MyStruct const &other) const;
                                bool operator!=(MyStruct const &other) const;
                            
                            bool MyStruct::operator==(const MyStruct &other) const
                            {
                                // compare members 
                                return true;
                            }
                            
                            bool MyStruct::operator!=(MyStruct const &other) const
                            {
                                return !(*this == other);
                            }
                            
                            P Offline
                            P Offline
                            pra7
                            wrote on last edited by
                            #15

                            @Wieland That worked !!! Thanks, How to know that which all operators should be overloaded?

                            ? 1 Reply Last reply
                            1
                            • P pra7

                              @Wieland That worked !!! Thanks, How to know that which all operators should be overloaded?

                              ? Offline
                              ? Offline
                              A Former User
                              wrote on last edited by
                              #16

                              @pra7 said in Best way to access a cpp structure in QML:

                              How to know that which all operators should be overloaded?

                              You can't really know. But when the compiler complains about a missing operator, just implement it. In this case we didn't really need the == operator, but I'd say it's common practice to implement the != operator using the == operator.

                              P 1 Reply Last reply
                              3
                              • ? A Former User

                                @pra7 said in Best way to access a cpp structure in QML:

                                How to know that which all operators should be overloaded?

                                You can't really know. But when the compiler complains about a missing operator, just implement it. In this case we didn't really need the == operator, but I'd say it's common practice to implement the != operator using the == operator.

                                P Offline
                                P Offline
                                pra7
                                wrote on last edited by
                                #17

                                @Wieland Thanks for all your suggestions.

                                1 Reply Last reply
                                1
                                • P pra7

                                  @Wieland Is there any possibility that I can access structure inside a structure?

                                  struct MyStruct {
                                  Q_GADGET
                                  int m_val;
                                  QString m_name1;
                                  QString m_name2;
                                  QString m_name3;
                                  QString m_name4;
                                  MyNewStruct m_newStr; //** new Struct includes Q_GADGET macro and member definations. 
                                  
                                  Q_PROPERTY(int val MEMBER m_val)
                                  Q_PROPERTY(QString name1 MEMBER m_name1)
                                  Q_PROPERTY(QString name2 MEMBER m_name2)
                                  Q_PROPERTY(QString name3 MEMBER m_name3)
                                  Q_PROPERTY(QString name4 MEMBER m_name4)
                                  
                                  Q_PROPERTY(MyNewStruct newStr MEMBER m_newStr) //**Currently getting error 
                                  };
                                  
                                  M Offline
                                  M Offline
                                  Mammamia
                                  wrote on last edited by
                                  #18

                                  @pra7, @Wieland how can I access a list of Structure inside another Structure.
                                  Eg: From the above example, I need to use

                                  QList<MyNewStructure> m_StructList;
                                  
                                  How is that possible? I have tried,
                                  QList<MyNewStructure> m_StructList;
                                  
                                  Q_PROPERTY(QList<MyNewStruct> newStr MEMBER m_newStr) but didnt help.
                                  
                                  1 Reply Last reply
                                  0
                                  • P pra7

                                    @Wieland Thanks!!! for your suggestion after lot of reading and searching I got the answer ,Actually we can use structs or any object which is not derived from QObject by using Q_GADGET :

                                    struct MyStruct {
                                        Q_GADGET
                                        int m_val;
                                        QString m_name1;
                                        QString m_name2;
                                        QString m_name3;
                                        QString m_name4;
                                        Q_PROPERTY(int val MEMBER m_val)
                                        Q_PROPERTY(QString name1 MEMBER m_name1)
                                        Q_PROPERTY(QString name2 MEMBER m_name2)
                                        Q_PROPERTY(QString name3 MEMBER m_name3)
                                        Q_PROPERTY(QString name4 MEMBER m_name4)
                                    };
                                    

                                    Then in my class i just replaced QVariant as below :

                                    class MyClass:public QObject
                                    {
                                        Q_OBJECT
                                        Q_PROPERTY(MyStruct mystr READ getMyStruct
                                                    WRITE setMyStruct NOTIFY myStructChanged)
                                    
                                    public:
                                        explicit MyClass(QObject *parent = nullptr);
                                        MyStruct strObj;
                                    
                                         // Edit: changed get function
                                         MyStruct getMyStruct() const
                                         {
                                             return strObj;
                                         }
                                    
                                    // Edit: Added set function
                                         void setMyStruct(myStruct val)
                                            {
                                                mystr = val;
                                                emit myStructChanged();
                                            }
                                    signals:
                                    void myStructChanged();
                                    
                                    }
                                    

                                    Now in QML file i can just use classObj.mystr.name1 to access the members and i can just use classObj.mystr.name1 = "abc" to set the values.

                                    S Offline
                                    S Offline
                                    seyed
                                    wrote on last edited by
                                    #19

                                    @pra7 but it does not sufficient! I had to use Q_DECLARE_METATYPE() and qRegisterMetaType<>() to avoid unknown type error. Did I missed something?

                                    1 Reply Last reply
                                    0
                                    • R Rua3n referenced this topic on
                                    • R Rua3n referenced this topic on

                                    • Login

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