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

Submodel into model



  • Hi,

    In my application, I have a simple model (to share variable to QML)

    Header :

    class ScreenModel : public QObject
    {
        Q_OBJECT
        Q_PROPERTY( int positionLogique READ getPositionLogique WRITE setPositionLogique NOTIFY positionLogiqueChanged )
        Q_PROPERTY( int couleurFondLCD READ getCouleurFondLCD WRITE setCouleurFondLCD NOTIFY couleurFondLCDChanged)
        Q_PROPERTY( int couleurReticule READ getCouleurReticule WRITE setCouleurReticule NOTIFY couleurReticuleChanged)
        Q_PROPERTY( int nombreEcran READ getNombreEcran WRITE setNombreEcran NOTIFY nombreEcranChanged)
    public:
        explicit ScreenModel(QObject *parent = 0);
    
        void setPositionLogique(QVariant PositionLogique);
        void setCouleurFondLCD(QVariant CouleurFondLCD);
        void setCouleurReticule(QVariant CouleurReticule);
        void setNombreEcran(QVariant NombreEcran);
    
        inline int getPositionLogique() const { return m_PositionLogique; }
        inline int getCouleurFondLCD() const { return m_CouleurFondLCD; }
        inline int getCouleurReticule() const { return m_CouleurReticule; }
        inline int getNombreEcran() const { return m_NombreEcran; }
    
    signals:
    
        void positionLogiqueChanged();
        void couleurFondLCDChanged();
        void couleurReticuleChanged();
        void nombreEcranChanged();
    
    public slots:
    
    private:
        int m_PositionLogique;
        int m_CouleurFondLCD;
        int m_CouleurReticule;
        int m_NombreEcran;
    };
    

    I would insert a model herited from QAbstractListModel into that one, and keeping the notification behavior of that last one.

    This is the model I would insert:

    #ifndef CUSTOMSCREENMODEL_H
    #define CUSTOMSCREENMODEL_H
    
    #include <QObject>
    #include <QAbstractListModel>
    
    
    class CustomScreenItem
    {
    
    public:
        /*
        \fn Constructor
        */
        CustomScreenItem(const int &ChannelIndex, const QString &Channel, const int &PositionReticule);
    
        /*
        \fn Setters
        */
        void setChannelIndex(QVariant ChannelIndex);
        void setChannel(QVariant Channel);
        void setPositionReticule(QVariant PositionReticule);
    
        /*
        \fn Getters
        */
        inline int ChannelIndex() const { return m_ChannelIndex; }
        inline QString Channel() const { return m_Channel; }
        inline int PositionReticule() const { return m_PositionReticule; }
    
    private:
        int m_ChannelIndex;
        QString m_Channel;
        int m_PositionReticule;
    };
    
    class CustomScreenModel : public QAbstractListModel
    {
        Q_OBJECT
    public:
        enum CustomScreenRoles {
            ChannelIndexRole = Qt::UserRole+1,
            ChannelRole,
            PositionReticuleRole
        };
        CustomScreenModel(QObject *parent = 0);
        void addTriggerComplexItem(const CustomScreenItem &customScreenItem);
        Q_INVOKABLE void append(const int &ChannelIndex, const QString &Channel, const int &PositionReticule);
        Q_INVOKABLE int rowCount(const QModelIndex & parent = QModelIndex()) const;
        QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
        QVariant headerData(int section, Qt::Orientation orientation, int role) const;
        bool setData(const QModelIndex &index, const QVariant &value, int role);
        Qt::ItemFlags flags(const QModelIndex &index) const;
        Q_INVOKABLE bool removeRow(const int index);
        Q_INVOKABLE QVariantMap get(int idx) const;
    signals:
        void dataChanged();
    protected:
        QHash<int, QByteArray> roleNames() const;
    private:
        QList<CustomScreenItem> m_customScreenItem;
    };
    #endif // CUSTOMSCREENMODEL_H
    
    

    Thank you


  • Moderators

    @RomanoFX said:

    I would insert a model herited from QAbstractListModel into that one, and keeping the notification behavior of that last one.

    what exactly do you mean?

    You wrapper class doesn't inherit from QAbstractItemModel, so you can't set it directly to an item view widget.
    Why not creating a simple getter method to get a pointer to the internal model and keep working with it.
    Your wrapper class can connect to any signal from the model.



  • Hi @raven-worx ,

    Thank you for your answer.

    I would have my ScreenModel like this :
    4 datas : positionLogique, couleurFondLCD, couleurReticule and nombreEcran
    x2 CustomScreenModel

    Should I declare two instances of CustomScreenModel as Q_PROPERTY?

    According to yours questions, CustomScreenModel inherits from QAbstractListModel (class CustomScreenModel : public QAbstractListModel), but every item (CustomScreenItem) is not inherited from QAbstractItemModel.
    Maybe am I wrong?

    Thank you


  • Moderators

    @RomanoFX
    may it be that you just want to use your ScreenModel class simply as interface?



  • I think I found the right way to do that :

    class ScreenModel : public QObject
    {
        Q_OBJECT
        Q_PROPERTY( int positionLogique READ getPositionLogique WRITE setPositionLogique NOTIFY positionLogiqueChanged )
        Q_PROPERTY( int couleurFondLCD READ getCouleurFondLCD WRITE setCouleurFondLCD NOTIFY couleurFondLCDChanged)
        Q_PROPERTY( int couleurReticule READ getCouleurReticule WRITE setCouleurReticule NOTIFY couleurReticuleChanged)
        Q_PROPERTY( int nombreEcran READ getNombreEcran WRITE setNombreEcran NOTIFY nombreEcranChanged)
        Q_PROPERTY( CustomScreenModel* custom1 READ custom1 WRITE setCustom1 )
    public:
        explicit ScreenModel(QObject *parent = 0);
    
        void setPositionLogique(QVariant PositionLogique);
        void setCouleurFondLCD(QVariant CouleurFondLCD);
        void setCouleurReticule(QVariant CouleurReticule);
        void setNombreEcran(QVariant NombreEcran);
        void setCustom1(CustomScreenModel* Custom1);
    
        inline int getPositionLogique() const { return m_PositionLogique; }
        inline int getCouleurFondLCD() const { return m_CouleurFondLCD; }
        inline int getCouleurReticule() const { return m_CouleurReticule; }
        inline int getNombreEcran() const { return m_NombreEcran; }
        inline CustomScreenModel *custom1() const { return m_Custom1; }
        //inline CustomScreenModel getNombreEcran() const { return m_NombreEcran; }
    
    
    
    signals:
    
        void positionLogiqueChanged();
        void couleurFondLCDChanged();
        void couleurReticuleChanged();
        void nombreEcranChanged();
    
    public slots:
    
    private:
        int m_PositionLogique;
        int m_CouleurFondLCD;
        int m_CouleurReticule;
        int m_NombreEcran;
        CustomScreenModel *m_Custom1;
    

    I should add NOTIFY behavior. Is this correct?
    It makes possible to access some models into that interface


Log in to reply