Important: Please read the 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{
        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);
        Planning *m_plan;
        bool m_signalConnected;

    //Planning class

    class Planning: public QObject
        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)
        explicit Planning(QObject *parent=Q_NULLPTR);
    public slots:
        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);
        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
        Manager(QObject *parent=Q_NULLPTR);
       Q_INVOKABLE Planning * getPlanning(void);
    public slots:
        Q_INVOKABLE void addPlanning(int i, Planning * plan);
            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.