Maggie Maggie - 2 months ago 50
C++ Question

QML,How to dynamicaly change Item of Repeater from C++

I have QML Repeater on Grid, when i clicked on item i emit signal which processed by C++ class, and then changed array in C++ which then assign as model of QML Repeater. Is there a way to change just two elements of C++ model, not whole model as i did?

that's my qml file

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)

}
}

}

}


C++ method which update model of QML Repeater

void ChessFiguresClass::changeModel()
{
QStringList dataList;

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

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

Answer

I'm afraid it is not possible. QList (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. I hope this help you.

Comments