c++qtqmlrepeater

How to dynamicaly change Items of a Repeater from C++


I have a QML Repeater on a Grid, when I click on an item, I emit a signal which is processed by a C++ class. Then, I change an array in C++ which is then assigned as a model of the QML Repeater.

Is there a way to change just two elements of the C++ model, not the whole model as I did?

QML code:

Grid{
    height:width
    rows:8
    columns: 8
    
    Repeater{
        id: chessPiecesRptr
           ...
        signal chessfigureSelected(int index)
        
    
        delegate: Item{
            id:chessPiecesItm
    
            Image{
                ...
            }

            MouseArea
            {
                anchors.fill:parent
                onClicked: {
                    chessPiecesRptr.chessfigureSelected(index)
                }
            }
        }
    }
}

The C++ method which updates the Repeater's model:

void ChessFiguresClass::changeModel()
{
    QStringList dataList;

    for(int i=0;i<64;i++)
        dataList.append(QChar(posArray[i]));

    QQmlProperty::write(chessPiecesRptr, "model",   QVariant::fromValue(dataList));
}

Solution

  • I'm afraid it is not possible. QList<T> (and QStringList) does not have inner mechanisms to notify Qml items about its changes. Only when model property from QML item is changed, the whole list is read again.

    I had faced the same problem before, and I implemented a string list using QAbstractListModel as base class. The header looks like this:

    #ifndef _SIMPLEMODEL_H_
    #define _SIMPLEMODEL_H_
    
    #include <QtCore>
    
    class SimpleStringModel : public QAbstractListModel
    {
        Q_PROPERTY(int count READ count NOTIFY countChanged)
        Q_DISABLE_COPY(SimpleStringModel)
        Q_OBJECT
    public:
        explicit SimpleStringModel(QObject* parent = 0);
        SimpleStringModel(const QList<QString>& initList, QObject* parent = 0);
        virtual ~SimpleStringModel();
    
    private:
        enum Roles{
            ModelDataRole = Qt::UserRole+1
        };
    
    public:
        int count() const;
    
    public:
    
        void append(const QString& item);
        void insert(int index, const QString& item);
        void append(const QList<QString>& items);
        void insert(int index, const QList<QString>& items);
        bool removeOne(const QString& item);
        int removeAll(const QString& item);
        void removeAt(int index);
        QList<QString> list() const;
    
    signals:
        void countChanged();
    
        // QAbstractItemModel interface
    public:
        virtual int rowCount(const QModelIndex &parent) const;
        virtual QVariant data(const QModelIndex &index, int role) const;
        virtual QHash<int, QByteArray> roleNames() const;
    
    private:
        QList<QString> m_data;
    };
    
    #endif //_SIMPLEMODEL_H_
    

    You can get all the code here (archive).