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. Access to nested c++ objects in QML?

Access to nested c++ objects in QML?

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
6 Posts 2 Posters 3.2k 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.
  • AlienA Offline
    AlienA Offline
    Alien
    wrote on last edited by Alien
    #1

    Hey,
    Imagine you have a page that it contains one or more menus and each menus has one or more keys inside and each keys has its features, how to export it into QML in a way all of nested objects inside higher level class be accessible?

    I've tried inheritance from QObject and using QVector to store variable number of nested objects but I faced to a lots of problems.

    For instance I want to access to keys feature with something like below snippet code:

    Rectangle
    {
    width:100
    height:100
    color:"red"
    Text{
    anchors{centerIn:parent}
    text:CPM.CPage[0].CMenus[0].CKeys[0].Name
    }
    }
    

    Yours,
    Ali

    raven-worxR 1 Reply Last reply
    0
    • AlienA Alien

      Hey,
      Imagine you have a page that it contains one or more menus and each menus has one or more keys inside and each keys has its features, how to export it into QML in a way all of nested objects inside higher level class be accessible?

      I've tried inheritance from QObject and using QVector to store variable number of nested objects but I faced to a lots of problems.

      For instance I want to access to keys feature with something like below snippet code:

      Rectangle
      {
      width:100
      height:100
      color:"red"
      Text{
      anchors{centerIn:parent}
      text:CPM.CPage[0].CMenus[0].CKeys[0].Name
      }
      }
      

      Yours,
      Ali

      raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by raven-worx
      #2

      @Alien said in Access to nested c++ objects in QML?:

      I've tried inheritance from QObject and using QVector to store variable number of nested objects but I faced to a lots of problems.

      What were your problems?
      Also you should use QVariantList and/or QVariantMap instead. See here.

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      1 Reply Last reply
      0
      • AlienA Offline
        AlienA Offline
        Alien
        wrote on last edited by Alien
        #3

        Dear @raven-worx ,

        In fact the problem is something ridiculous, I don't expect that something like this become a problem to me!
        By the way could you please have a look at the below code :

        Key Header:

        #ifndef CKEY_H
        #define CKEY_H
        
        #include <QObject>
        #include <QColor>
        #include <QString>
        
        class CKey:public QObject
        {
        Q_OBJECT
            Q_PROPERTY(QString Name READ name WRITE setName NOTIFY nameChanged)
            Q_PROPERTY(int Number READ number WRITE setNumber NOTIFY numberChanged)
            Q_PROPERTY(QColor Color READ color WRITE setColor NOTIFY colorChanged)
        private:
            QString m_name;
            int m_number;
            QColor m_color;
        public:
            CKey(QObject *parent=nullptr);
        
            QString name() const;
            void setName(const QString &name);
            int number() const;
            void setNumber(int number);
            QColor color() const;
            void setColor(const QColor &color);
        
            ~CKey();
        signals:
            void nameChanged();
            void numberChanged();
            void colorChanged();
        };
        
        #endif // CKEY_H
        
        

        Key source file :

        #include "ckey.h"
        
        
        /*=========================SETTER/GETTER================================*/
        QString CKey::name() const
        {
            return m_name;
        }
        
        void CKey::setName(const QString &name)
        {
            m_name = name;
            emit nameChanged();
        }
        
        int CKey::number() const
        {
            return m_number;
        }
        
        void CKey::setNumber(int number)
        {
            m_number = number;
            emit numberChanged();
        }
        
        QColor CKey::color() const
        {
            return m_color;
        }
        
        void CKey::setColor(const QColor &color)
        {
            m_color = color;
            emit colorChanged();
        }
        
        
        /*=====================================================================*/
        CKey::CKey(QObject *parent):QObject(parent)
        {
            m_color = Qt::red;
            m_number = 0;
            m_name="default";
        
        }
        /*=====================================================================*/
        
        /*=====================================================================*/
        CKey::~CKey()
        {
        
        }
        /*=====================================================================*/
        
        

        Menu Header:

        #ifndef CMENU_H
        #define CMENU_H
        
        #include <QObject>
        #include <QString>
        #include <QVector>
        #include "ckey.h"
        
        class CMenu : public QObject
        {
            Q_OBJECT
            Q_PROPERTY(QString Name READ name WRITE setName NOTIFY nameChanged)
            Q_PROPERTY(QVector<CKey> KeysList READ keysList WRITE setKeysList NOTIFY keysListChanged)
        private :
            QString m_name;
            QVector<CKey> m_keysList;
        
        public:
            explicit CMenu(QObject *parent = nullptr);
            ~CMenu();
        
            QString name() const;
            void setName(const QString &name);
        
            QVector<CKey> keysList() const;
            void setKeysList(const QVector<CKey> &keysList);
        
        signals:
            void nameChanged();
            void keysListChanged();
        
        public slots:
        };
        
        #endif // CMENU_H
        
        

        Menu source file:

        #include "cmenu.h"
        
        QString CMenu::name() const
        {
            return m_name;
        }
        
        void CMenu::setName(const QString &name)
        {
            m_name = name;
        }
        
        QVector<CKey> CMenu::keysList() const
        {
            return m_keysList;
        }
        
        void CMenu::setKeysList(const QVector<CKey> &keysList)
        {
            m_keysList = keysList;
        }
        
        CMenu::CMenu(QObject *parent) : QObject(parent)
        {
        
        }
        
        CMenu::~CMenu()
        {
            if(m_keysList.length()>0)
                m_keysList.clear();
        
        }
        
        

        And finally main:

        #include <QGuiApplication>
        #include <QQmlApplicationEngine>
        #include <QQmlContext>
        #include "ckey.h"
        #include "cmenu.h"
        
        int main(int argc, char *argv[])
        {
        
            CKey key[5];
        
            key[0].setName("One");
            key[1].setName("TWO");
            key[2].setName("THREE");
            key[3].setName("FOUR");
            key[4].setName("FIVE");
        
            CMenu menu;
        
            for (int index = 0; index < 5; ++index)
            {
                    menu.keysList().append(key[index]);
            }
        #if defined(Q_OS_WIN)
            QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
        #endif
        
            QGuiApplication app(argc, argv);
            QQmlApplicationEngine engine;
            engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
            if (engine.rootObjects().isEmpty())
                return -1;
            QQmlContext * context=engine.rootContext();
            context->setContextProperty("CMenu",&menu);
            return app.exec();
        }
        
        

        Compile Errors:
        error: use of deleted function 'CKey& CKey::operator=(const CKey&)'
        use of deleted function 'CKey::CKey(const CKey&)'
        Of course these errors say to me that CKey need to implement operator = and CKey(const CKey&) but why?Does it have any better way to doing that?

        raven-worxR 1 Reply Last reply
        0
        • AlienA Alien

          Dear @raven-worx ,

          In fact the problem is something ridiculous, I don't expect that something like this become a problem to me!
          By the way could you please have a look at the below code :

          Key Header:

          #ifndef CKEY_H
          #define CKEY_H
          
          #include <QObject>
          #include <QColor>
          #include <QString>
          
          class CKey:public QObject
          {
          Q_OBJECT
              Q_PROPERTY(QString Name READ name WRITE setName NOTIFY nameChanged)
              Q_PROPERTY(int Number READ number WRITE setNumber NOTIFY numberChanged)
              Q_PROPERTY(QColor Color READ color WRITE setColor NOTIFY colorChanged)
          private:
              QString m_name;
              int m_number;
              QColor m_color;
          public:
              CKey(QObject *parent=nullptr);
          
              QString name() const;
              void setName(const QString &name);
              int number() const;
              void setNumber(int number);
              QColor color() const;
              void setColor(const QColor &color);
          
              ~CKey();
          signals:
              void nameChanged();
              void numberChanged();
              void colorChanged();
          };
          
          #endif // CKEY_H
          
          

          Key source file :

          #include "ckey.h"
          
          
          /*=========================SETTER/GETTER================================*/
          QString CKey::name() const
          {
              return m_name;
          }
          
          void CKey::setName(const QString &name)
          {
              m_name = name;
              emit nameChanged();
          }
          
          int CKey::number() const
          {
              return m_number;
          }
          
          void CKey::setNumber(int number)
          {
              m_number = number;
              emit numberChanged();
          }
          
          QColor CKey::color() const
          {
              return m_color;
          }
          
          void CKey::setColor(const QColor &color)
          {
              m_color = color;
              emit colorChanged();
          }
          
          
          /*=====================================================================*/
          CKey::CKey(QObject *parent):QObject(parent)
          {
              m_color = Qt::red;
              m_number = 0;
              m_name="default";
          
          }
          /*=====================================================================*/
          
          /*=====================================================================*/
          CKey::~CKey()
          {
          
          }
          /*=====================================================================*/
          
          

          Menu Header:

          #ifndef CMENU_H
          #define CMENU_H
          
          #include <QObject>
          #include <QString>
          #include <QVector>
          #include "ckey.h"
          
          class CMenu : public QObject
          {
              Q_OBJECT
              Q_PROPERTY(QString Name READ name WRITE setName NOTIFY nameChanged)
              Q_PROPERTY(QVector<CKey> KeysList READ keysList WRITE setKeysList NOTIFY keysListChanged)
          private :
              QString m_name;
              QVector<CKey> m_keysList;
          
          public:
              explicit CMenu(QObject *parent = nullptr);
              ~CMenu();
          
              QString name() const;
              void setName(const QString &name);
          
              QVector<CKey> keysList() const;
              void setKeysList(const QVector<CKey> &keysList);
          
          signals:
              void nameChanged();
              void keysListChanged();
          
          public slots:
          };
          
          #endif // CMENU_H
          
          

          Menu source file:

          #include "cmenu.h"
          
          QString CMenu::name() const
          {
              return m_name;
          }
          
          void CMenu::setName(const QString &name)
          {
              m_name = name;
          }
          
          QVector<CKey> CMenu::keysList() const
          {
              return m_keysList;
          }
          
          void CMenu::setKeysList(const QVector<CKey> &keysList)
          {
              m_keysList = keysList;
          }
          
          CMenu::CMenu(QObject *parent) : QObject(parent)
          {
          
          }
          
          CMenu::~CMenu()
          {
              if(m_keysList.length()>0)
                  m_keysList.clear();
          
          }
          
          

          And finally main:

          #include <QGuiApplication>
          #include <QQmlApplicationEngine>
          #include <QQmlContext>
          #include "ckey.h"
          #include "cmenu.h"
          
          int main(int argc, char *argv[])
          {
          
              CKey key[5];
          
              key[0].setName("One");
              key[1].setName("TWO");
              key[2].setName("THREE");
              key[3].setName("FOUR");
              key[4].setName("FIVE");
          
              CMenu menu;
          
              for (int index = 0; index < 5; ++index)
              {
                      menu.keysList().append(key[index]);
              }
          #if defined(Q_OS_WIN)
              QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
          #endif
          
              QGuiApplication app(argc, argv);
              QQmlApplicationEngine engine;
              engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
              if (engine.rootObjects().isEmpty())
                  return -1;
              QQmlContext * context=engine.rootContext();
              context->setContextProperty("CMenu",&menu);
              return app.exec();
          }
          
          

          Compile Errors:
          error: use of deleted function 'CKey& CKey::operator=(const CKey&)'
          use of deleted function 'CKey::CKey(const CKey&)'
          Of course these errors say to me that CKey need to implement operator = and CKey(const CKey&) but why?Does it have any better way to doing that?

          raven-worxR Offline
          raven-worxR Offline
          raven-worx
          Moderators
          wrote on last edited by raven-worx
          #4

          @Alien said in Access to nested c++ objects in QML?:

          QVector<CKey>

          The errors are because you use a QObject derived class a reference/copy type. This is not allowed. QObject must be allocated on the heap (=pointers).
          So change your declaration and properties to QList<CKey*>

          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
          If you have a question please use the forum so others can benefit from the solution in the future

          1 Reply Last reply
          0
          • AlienA Offline
            AlienA Offline
            Alien
            wrote on last edited by Alien
            #5

            Dear @raven-worx,
            I changed the CMenu class to below:

            Header

            #ifndef CMENU_H
            #define CMENU_H
            
            #include <QObject>
            #include <QString>
            #include <QVector>
            #include "ckey.h"
            
            class CMenu : public QObject
            {
                Q_OBJECT
                Q_PROPERTY(QString Name READ name WRITE setName NOTIFY nameChanged)
                Q_PROPERTY(QList<CKey*> KeysList READ keysList NOTIFY keysListChanged)
            private :
                QString m_name;
                QList<CKey*> m_keysList;
            
            public:
                explicit CMenu(QObject *parent = nullptr);
                ~CMenu();
            
                QString name() const;
                void setName(const QString &name);
                void addKey(CKey* key);
            
                QList<CKey*> keysList() const;
            
            signals:
                void nameChanged();
                void keysListChanged();
            
            public slots:
            };
            
            #endif // CMENU_H
            
            
            

            source

            #include "cmenu.h"
            
            QString CMenu::name() const
            {
                return m_name;
            }
            
            void CMenu::setName(const QString &name)
            {
                m_name = name;
            }
            
            void CMenu::addKey(CKey *key)
            {
                m_keysList.append(key);
            }
            
            QList<CKey *> CMenu::keysList() const
            {
                return m_keysList;
            }
            
            
            
            CMenu::CMenu(QObject *parent) : QObject(parent)
            {
            
            }
            
            CMenu::~CMenu()
            {
                if(m_keysList.length()>0)
                    m_keysList.clear();
            
            }
            
            

            and main.cpp:

            #include <QGuiApplication>
            #include <QQmlApplicationEngine>
            #include <QQmlContext>
            #include "ckey.h"
            #include "cmenu.h"
            
            int main(int argc, char *argv[])
            {
            
                CKey *key = new CKey[5];
            
                key[0].setName("One");
                key[1].setName("TWO");
                key[2].setName("THREE");
                key[3].setName("FOUR");
                key[4].setName("FIVE");
            
                CMenu menu;
                menu.setName("Test");
            
                for (int index = 0; index < 5; ++index)
                {
                    menu.addKey(&key[index]);
                }
            
            
            #if defined(Q_OS_WIN)
                QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
            #endif
            
                QGuiApplication app(argc, argv);
                QQmlApplicationEngine engine;
                engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
                if (engine.rootObjects().isEmpty())
                    return -1;
                QQmlContext * context=engine.rootContext();
                context->setContextProperty("CMenu",&menu);
                return app.exec();
            }
            
            

            it build correctly now how to access to keys from qml:

            import QtQuick 2.10
            import QtQuick.Window 2.10
            
            Window {
                visible: true
                width: 640
                height: 480
                title: qsTr("Hello World")
            
            
                Rectangle
                {
                    width:150
                    height: 150
                    color: "yellow"
                    Text {
                        id: txtID
                        text: qsTr(CMenu.KeysList.at(0).Name)
                    }
                }
            }
            
            

            Errors:

            qrc:/main.qml:18: ReferenceError: CMenu is not defined
            qrc:/main.qml:18: TypeError: Property 'at' of object QVariant(QVector<CKey*>) is not a function

            How to access to CKey's attributes from Cmenu in QML?

            raven-worxR 1 Reply Last reply
            0
            • AlienA Alien

              Dear @raven-worx,
              I changed the CMenu class to below:

              Header

              #ifndef CMENU_H
              #define CMENU_H
              
              #include <QObject>
              #include <QString>
              #include <QVector>
              #include "ckey.h"
              
              class CMenu : public QObject
              {
                  Q_OBJECT
                  Q_PROPERTY(QString Name READ name WRITE setName NOTIFY nameChanged)
                  Q_PROPERTY(QList<CKey*> KeysList READ keysList NOTIFY keysListChanged)
              private :
                  QString m_name;
                  QList<CKey*> m_keysList;
              
              public:
                  explicit CMenu(QObject *parent = nullptr);
                  ~CMenu();
              
                  QString name() const;
                  void setName(const QString &name);
                  void addKey(CKey* key);
              
                  QList<CKey*> keysList() const;
              
              signals:
                  void nameChanged();
                  void keysListChanged();
              
              public slots:
              };
              
              #endif // CMENU_H
              
              
              

              source

              #include "cmenu.h"
              
              QString CMenu::name() const
              {
                  return m_name;
              }
              
              void CMenu::setName(const QString &name)
              {
                  m_name = name;
              }
              
              void CMenu::addKey(CKey *key)
              {
                  m_keysList.append(key);
              }
              
              QList<CKey *> CMenu::keysList() const
              {
                  return m_keysList;
              }
              
              
              
              CMenu::CMenu(QObject *parent) : QObject(parent)
              {
              
              }
              
              CMenu::~CMenu()
              {
                  if(m_keysList.length()>0)
                      m_keysList.clear();
              
              }
              
              

              and main.cpp:

              #include <QGuiApplication>
              #include <QQmlApplicationEngine>
              #include <QQmlContext>
              #include "ckey.h"
              #include "cmenu.h"
              
              int main(int argc, char *argv[])
              {
              
                  CKey *key = new CKey[5];
              
                  key[0].setName("One");
                  key[1].setName("TWO");
                  key[2].setName("THREE");
                  key[3].setName("FOUR");
                  key[4].setName("FIVE");
              
                  CMenu menu;
                  menu.setName("Test");
              
                  for (int index = 0; index < 5; ++index)
                  {
                      menu.addKey(&key[index]);
                  }
              
              
              #if defined(Q_OS_WIN)
                  QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
              #endif
              
                  QGuiApplication app(argc, argv);
                  QQmlApplicationEngine engine;
                  engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
                  if (engine.rootObjects().isEmpty())
                      return -1;
                  QQmlContext * context=engine.rootContext();
                  context->setContextProperty("CMenu",&menu);
                  return app.exec();
              }
              
              

              it build correctly now how to access to keys from qml:

              import QtQuick 2.10
              import QtQuick.Window 2.10
              
              Window {
                  visible: true
                  width: 640
                  height: 480
                  title: qsTr("Hello World")
              
              
                  Rectangle
                  {
                      width:150
                      height: 150
                      color: "yellow"
                      Text {
                          id: txtID
                          text: qsTr(CMenu.KeysList.at(0).Name)
                      }
                  }
              }
              
              

              Errors:

              qrc:/main.qml:18: ReferenceError: CMenu is not defined
              qrc:/main.qml:18: TypeError: Property 'at' of object QVariant(QVector<CKey*>) is not a function

              How to access to CKey's attributes from Cmenu in QML?

              raven-worxR Offline
              raven-worxR Offline
              raven-worx
              Moderators
              wrote on last edited by
              #6

              @Alien said in Access to nested c++ objects in QML?:

              How to access to CKey's attributes from Cmenu in QML?

              When you just want to read values:

              CMenu {
                  id: cm
              }
              ...
              cm.KeysList[0].Name
              

              --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
              If you have a question please use the forum so others can benefit from the solution in the future

              1 Reply Last reply
              1

              • Login

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