Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Exposing C++ model as Q_PROPERTY ?



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



  • @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:"



  • @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!


  • Moderators

    @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



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