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. Exposing C++ model as Q_PROPERTY ?
QtWS25 Last Chance

Exposing C++ model as Q_PROPERTY ?

Scheduled Pinned Locked Moved Solved QML and Qt Quick
qmltableview tabletable model
5 Posts 4 Posters 1.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.
  • B Offline
    B Offline
    Babs
    wrote on 10 Mar 2020, 15:29 last edited by Babs 3 Oct 2020, 15:34
    #1

    Hello,
    Is it possible to expose a C++ model as a Q_PROPERTY.
    In my project , i have a class Planning containing a list of Object Palier that i must display as a table in QML. I create a model class for the object Palier.

    class PalierModel: public QAbstractTableModel
    {
        enum PalierDetails{
            valueRole=Qt::UserRole,
            debitRole=Qt::UserRole+1,
            distanceRole=Qt::UserRole+2,
            iradTimeRole=Qt::UserRole+3,
            debutRole=Qt::UserRole+4,
            finRole=Qt::UserRole+5,
            tempsMesRole=Qt::UserRole+6
        };
    
    public:
        explicit PalierModel(QObject *parent= Q_NULLPTR);
        int rowCount(const QModelIndex &index=QModelIndex()) const override;
        int columnCount(const QModelIndex & = QModelIndex()) const override;
        QVariant data(const QModelIndex &index,int role=Qt::DisplayRole) const override;
        Qt::ItemFlags flags(const QModelIndex &index) const override;
        bool setData(const QModelIndex &index, const QVariant &value,int role) override;
        QHash<int,QByteArray> roleNames() const override;
        Planning *dataSource() const;
        void setDataSource(Planning *plan);
    
    private:
        Planning *m_plan;
        bool m_signalConnected;
    };
    

    //Planning class

    class Planning: public QObject
    {
        Q_OBJECT
        Q_PROPERTY(int doseParameter READ doseParameter WRITE setDoseParameter NOTIFY doseParameterChanged)
        Q_PROPERTY(int numOfSteps READ numOfSteps WRITE setNumOfSteps NOTIFY numOfStepsChanged)
        Q_PROPERTY(double distance READ distance WRITE setDistance NOTIFY distanceChanged)
        Q_PROPERTY(int timeBetweenSteps READ timeBetweenSteps WRITE setTimeBetweenSteps NOTIFY timeBetweenStepsChanged)
        Q_PROPERTY(QString startManipTime READ startManipTime WRITE setStartManipTime  NOTIFY startManipTimeChanged)
        Q_PROPERTY(QTime startHour READ startHour WRITE setStartHour NOTIFY startHourChanged)
        Q_PROPERTY(QTime endHour READ endHour WRITE setEndHour NOTIFY endHourChanged)
        Q_PROPERTY(QTime tempsMesure READ tempsMesure WRITE setTempsMesure NOTIFY tempsMesureChanged)
        Q_PROPERTY(QString userName READ userName WRITE setUserName NOTIFY userNameChanged)
        Q_PROPERTY(PalierModel myModel READ myModel)
    
    public:
        explicit Planning(QObject *parent=Q_NULLPTR);
    
    public slots:
    
    signals:
    
        void doseParameterChanged(int doseParameter);
    
        void numOfStepsChanged(int numOfSteps);
    
        void distanceChanged(double distance);
    
        void timeBetweenStepsChanged(int timeBetweenSteps);
    
        void startManipTimeChanged(QString startManipTime);
    
        void prePalierAdded();
    
        void postPalierAdded();
    
        void prePalierRemoved(int index);
    
        void postPalierRemoved();
    
        void startHourChanged(QTime startHour);
    
        void endHourChanged(QTime endHour);
    
        void tempsMesureChanged(QTime tempsMesure);
    
        void userNameChanged(QString userName);
    
    private:
        QMap<int,Palier*> m_paliers;
    
    };
    
    #endif // PLANNING_H
    

    I have a main class manager containing a list of objects Planning that i expose to QML.

    #ifndef MANAGER_H
    #define MANAGER_H
    
    #include <QObject>
    
    #include "planning.h"
    
    class Manager:public QObject
    {
        Q_OBJECT
    public:
        Manager(QObject *parent=Q_NULLPTR);
       Q_INVOKABLE Planning * getPlanning(void);
    
    public slots:
        Q_INVOKABLE void addPlanning(int i, Planning * plan);
    
    private:
            QMap<int,QObject*> m_plannings;
    };
    
    #endif // MANAGER_H
    
    

    My problem is that i need to display for each object planning a table in my QML. I will have multiple models thus. I'm wondering if i could just expose the model as Q_PROPERTY in classs Planning?
    Can anyone help pls?

    G 1 Reply Last reply 10 Mar 2020, 16:29
    0
    • B Babs
      10 Mar 2020, 15:29

      Hello,
      Is it possible to expose a C++ model as a Q_PROPERTY.
      In my project , i have a class Planning containing a list of Object Palier that i must display as a table in QML. I create a model class for the object Palier.

      class PalierModel: public QAbstractTableModel
      {
          enum PalierDetails{
              valueRole=Qt::UserRole,
              debitRole=Qt::UserRole+1,
              distanceRole=Qt::UserRole+2,
              iradTimeRole=Qt::UserRole+3,
              debutRole=Qt::UserRole+4,
              finRole=Qt::UserRole+5,
              tempsMesRole=Qt::UserRole+6
          };
      
      public:
          explicit PalierModel(QObject *parent= Q_NULLPTR);
          int rowCount(const QModelIndex &index=QModelIndex()) const override;
          int columnCount(const QModelIndex & = QModelIndex()) const override;
          QVariant data(const QModelIndex &index,int role=Qt::DisplayRole) const override;
          Qt::ItemFlags flags(const QModelIndex &index) const override;
          bool setData(const QModelIndex &index, const QVariant &value,int role) override;
          QHash<int,QByteArray> roleNames() const override;
          Planning *dataSource() const;
          void setDataSource(Planning *plan);
      
      private:
          Planning *m_plan;
          bool m_signalConnected;
      };
      

      //Planning class

      class Planning: public QObject
      {
          Q_OBJECT
          Q_PROPERTY(int doseParameter READ doseParameter WRITE setDoseParameter NOTIFY doseParameterChanged)
          Q_PROPERTY(int numOfSteps READ numOfSteps WRITE setNumOfSteps NOTIFY numOfStepsChanged)
          Q_PROPERTY(double distance READ distance WRITE setDistance NOTIFY distanceChanged)
          Q_PROPERTY(int timeBetweenSteps READ timeBetweenSteps WRITE setTimeBetweenSteps NOTIFY timeBetweenStepsChanged)
          Q_PROPERTY(QString startManipTime READ startManipTime WRITE setStartManipTime  NOTIFY startManipTimeChanged)
          Q_PROPERTY(QTime startHour READ startHour WRITE setStartHour NOTIFY startHourChanged)
          Q_PROPERTY(QTime endHour READ endHour WRITE setEndHour NOTIFY endHourChanged)
          Q_PROPERTY(QTime tempsMesure READ tempsMesure WRITE setTempsMesure NOTIFY tempsMesureChanged)
          Q_PROPERTY(QString userName READ userName WRITE setUserName NOTIFY userNameChanged)
          Q_PROPERTY(PalierModel myModel READ myModel)
      
      public:
          explicit Planning(QObject *parent=Q_NULLPTR);
      
      public slots:
      
      signals:
      
          void doseParameterChanged(int doseParameter);
      
          void numOfStepsChanged(int numOfSteps);
      
          void distanceChanged(double distance);
      
          void timeBetweenStepsChanged(int timeBetweenSteps);
      
          void startManipTimeChanged(QString startManipTime);
      
          void prePalierAdded();
      
          void postPalierAdded();
      
          void prePalierRemoved(int index);
      
          void postPalierRemoved();
      
          void startHourChanged(QTime startHour);
      
          void endHourChanged(QTime endHour);
      
          void tempsMesureChanged(QTime tempsMesure);
      
          void userNameChanged(QString userName);
      
      private:
          QMap<int,Palier*> m_paliers;
      
      };
      
      #endif // PLANNING_H
      

      I have a main class manager containing a list of objects Planning that i expose to QML.

      #ifndef MANAGER_H
      #define MANAGER_H
      
      #include <QObject>
      
      #include "planning.h"
      
      class Manager:public QObject
      {
          Q_OBJECT
      public:
          Manager(QObject *parent=Q_NULLPTR);
         Q_INVOKABLE Planning * getPlanning(void);
      
      public slots:
          Q_INVOKABLE void addPlanning(int i, Planning * plan);
      
      private:
              QMap<int,QObject*> m_plannings;
      };
      
      #endif // MANAGER_H
      
      

      My problem is that i need to display for each object planning a table in my QML. I will have multiple models thus. I'm wondering if i could just expose the model as Q_PROPERTY in classs Planning?
      Can anyone help pls?

      G Offline
      G Offline
      Gojir4
      wrote on 10 Mar 2020, 16:29 last edited by
      #2

      @Babs Hi,
      Yes you can. You need to expose a pointer as property, and also register the type of the model so it's known by the Qml Engine.
      Example :

      Q_PROPERTY(QMyModel *myModel READ myModel NOTIFY myModelChanged)
      

      You need to register the type before to use it, for example in the main() function:

      int main(int argc, char *argv[]){
          QGuiApplication app (argc, argv);
          qmlRegisterType<MyModel>("MyApp.Core", 1, 0, "MyModel");
          //.... loading and initializing QML
          return app.exec()
      

      Note that NOTIFY sinal is useless but only here to avoid the warning from Qml Engine "depends on non-NOTIFYable properties:"

      K R 2 Replies Last reply 10 Mar 2020, 16:51
      2
      • G Gojir4
        10 Mar 2020, 16:29

        @Babs Hi,
        Yes you can. You need to expose a pointer as property, and also register the type of the model so it's known by the Qml Engine.
        Example :

        Q_PROPERTY(QMyModel *myModel READ myModel NOTIFY myModelChanged)
        

        You need to register the type before to use it, for example in the main() function:

        int main(int argc, char *argv[]){
            QGuiApplication app (argc, argv);
            qmlRegisterType<MyModel>("MyApp.Core", 1, 0, "MyModel");
            //.... loading and initializing QML
            return app.exec()
        

        Note that NOTIFY sinal is useless but only here to avoid the warning from Qml Engine "depends on non-NOTIFYable properties:"

        K Offline
        K Offline
        KroMignon
        wrote on 10 Mar 2020, 16:51 last edited by
        #3

        @Gojir4 said in Exposing C++ model as Q_PROPERTY ?:

        Note that NOTIFY sinal is useless but only here to avoid the warning from Qml Engine "depends on non-NOTIFYable properties:"

        To avoid this warning, I guess it is better to declare the Q_PROTERTY as constant:

        Q_PROPERTY(QMyModel *myModel READ myModel CONSTANT)
        

        Another side note is to be aware of Data Ownership issues: ensure returned object instance has a parent or use QQmlEngine::setObjectOwnership(objectIntance, QQmlEngine::CppOwnership) to ensure Qml Engine will not take ownership and delete your object instance!

        It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

        1 Reply Last reply
        4
        • G Gojir4
          10 Mar 2020, 16:29

          @Babs Hi,
          Yes you can. You need to expose a pointer as property, and also register the type of the model so it's known by the Qml Engine.
          Example :

          Q_PROPERTY(QMyModel *myModel READ myModel NOTIFY myModelChanged)
          

          You need to register the type before to use it, for example in the main() function:

          int main(int argc, char *argv[]){
              QGuiApplication app (argc, argv);
              qmlRegisterType<MyModel>("MyApp.Core", 1, 0, "MyModel");
              //.... loading and initializing QML
              return app.exec()
          

          Note that NOTIFY sinal is useless but only here to avoid the warning from Qml Engine "depends on non-NOTIFYable properties:"

          R Offline
          R Offline
          raven-worx
          Moderators
          wrote on 10 Mar 2020, 19:33 last edited by
          #4

          @Gojir4 said in Exposing C++ model as Q_PROPERTY ?:

          You need to register the type before to use it, for example in the main() function:

          i think its not mandatory to register it this way

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

          B 1 Reply Last reply 11 Mar 2020, 08:57
          0
          • R raven-worx
            10 Mar 2020, 19:33

            @Gojir4 said in Exposing C++ model as Q_PROPERTY ?:

            You need to register the type before to use it, for example in the main() function:

            i think its not mandatory to register it this way

            B Offline
            B Offline
            Babs
            wrote on 11 Mar 2020, 08:57 last edited by
            #5

            Thanks you all. I'll try to do it.

            1 Reply Last reply
            0

            5/5

            11 Mar 2020, 08:57

            • Login

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