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

dataChange in QAbstractListModel doesn't work?



  • Hello,
    I implement a kind of custom model with QAbstractListModel and assign it to the Repeater in QML unfortunately when i update the model QML side cannot be aware of that and my data couldn't update.

    class CTransparentModel: public QAbstractListModel
    {
        //    Q_OBJECT
    private:
        int m_length;
    public:
        /*quint16 due to value of UserRole which is 256(0x100)*/
        enum class ECTRANSPARENT_MODEL_ROLE : quint16
        {
            Role_Lenght = Qt::UserRole + 1,
            ECTRANSPARENT_MODEL_ROLE_LENGHT,
        };
        void updateHappened();
        CTransparentModel(QObject *parent = nullptr);
        bool setTransparentModelLenght(const int& newLength);
    
        // QAbstractItemModel interface
    public:
    
        int rowCount(const QModelIndex &parent) const Q_DECL_OVERRIDE;
        QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;
        bool setData(const QModelIndex &index, const QVariant &value, int role) Q_DECL_OVERRIDE;
    };
    

    and implementation is:

    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    CTransparentModel::CTransparentModel(QObject *parent):QAbstractListModel (parent)
    {
        m_length = 0;
    }
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    void CTransparentModel::updateHappened()
    {
        QModelIndex br=createIndex(m_length-1,0);
        QModelIndex tl=createIndex(0,0);
        /*Does it have any problem*/
        emit dataChanged(tl,br);
    }
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    bool CTransparentModel::setTransparentModelLenght(const int &newLength)
    {
        m_length = newLength;
        QModelIndex br=createIndex(m_length-1,0);
        QModelIndex tl=createIndex(0,0);
        /*Doesn't work*/
        emit dataChanged(tl,br);
        return true;
    }
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    int CTransparentModel::rowCount(const QModelIndex &parent) const
    {
        Q_UNUSED(parent)
        return m_length;
    }
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    QVariant CTransparentModel::data(const QModelIndex &index, int role) const
    {
        if(index.row() < 0 || index.row() >= m_length)
        {
            return false;
        }
        if(role == static_cast<int>(ECTRANSPARENT_MODEL_ROLE::Role_Lenght))
        {
            return QVariant::fromValue(m_length);
        }
           return  QVariant();
    }
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    bool CTransparentModel::setData(const QModelIndex &index, const QVariant &value, int role)
    {
        if(index.row() < 0 || index.row() >= m_length)
        {
            return false;
        }
    
        if(role == static_cast<int>(ECTRANSPARENT_MODEL_ROLE::Role_Lenght))
        {
            m_length = value.value<int>();
        }
        else
        {
            return  false;
        }
        emit dataChanged(index,index);
        return true;
    }
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    Qt::ItemFlags CTransparentModel::flags(const QModelIndex &index) const
    {
        if (!index.isValid())
            return Qt::ItemIsEnabled;
    
        return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
    }
    

    QML side :

    import QtQuick 2.9
    
    Item {
    
        Repeater
        {
            model:TRANS_MODEL
            Rectangle
            {
                x:0
                y:index*25
                width: 100
                height: 20
                color: "lime"
                Text
                {
                    id: name
                    text: CPM.keyName(0,index)
                    anchors.centerIn: parent
                }
            }
        }
    
    }
    
    

    I implement it in UBUNTU16.0.4LTS and QT Creator4.3.1 Based on QT5.9.1

    What am I missing?

    I appreciate any help.


  • Lifetime Qt Champion

    Hi,

    How are you creating that model ?
    Where does it get modified ?



  • Dear @SGaist,
    Indeed this code doesn't modify any data I have a kind of nested and a little bit complex data hierarchy and I try to introduce simple model to qml in order to make my model be updated.I want to use it as a trick to qml.
    The main problem is that I have keys and labels that they are inside menus they are inside pages and pages are inside a page manager now I want to update something like status (enable,visibility,...),name,etc of keys if I create keymodel that is derived from QAbstractListModel all of my classes need to change properly so I decided to introduce a simple model to qml (this model doesn't have any data but report any chages that happend in undelaying data) and register this class to my "page manager" class so when something change in my data,
    "page manager" class invoke "updateHappened" function of my model to virtually this simple model update itself therefore Qml update its data, with that I expect that Qml find changes and finally update itself but it is never happend till now and I don't know why?

    Sorry for long story :)


  • Lifetime Qt Champion

    Hence my questions:
    How are you creating and managing it ? From C++ ? From QML ?



  • Dear @SGaist ,
    From C++ I manage it and just show in QML


Log in to reply