I have a C++ model derived from QAbstractListModel
which I am using in a QML ListView
ListView {
id: listView
populate: Transition {
id: addTrans
SequentialAnimation {
PauseAnimation {
duration: (addTrans.ViewTransition.index -
addTrans.ViewTransition.targetIndexes[0]) * 100
}
NumberAnimation { property: "scale"; from: 0; to: 1 }
}
}
anchors.fill: parent
delegate: listDelegate
model: newsModel
}
I tried to add an animation for when the list is populated, but it doesn't work. So what I did was I tried to change populate
to add
and the animation is triggered, however the problem is that that each item is already in the list when the animation starts: in other words, instead of having an empty list to which items are added, I have a full list of elements that are then individually animated. I have tried also following this suggestion but it doesn't work.
EDIT: as requested I am providing a minimal working example to reproduce my problem. The problem can be reproduced with the following:
#include <QObject>
#include <QQmlObjectListModel.h>
class Item : public QObject{
Q_OBJECT
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
public:
Item(QObject* parent = nullptr): QObject(parent)
{
}
QString name() const{
return mName;
}
void setName(QString const &name){
if(mName != name){
mName = name;
emit nameChanged();
}
}
signals:
void nameChanged();
private:
QString mName;
};
class DataManager : public QObject{
Q_OBJECT
Q_PROPERTY(QQmlObjectListModel<Item>* itemsModel READ itemsModel CONSTANT)
public:
DataManager(){
mItemsModel = new QQmlObjectListModel<Item>(this);
qRegisterMetaType<QQmlObjectListModel<Item>*>("QQmlObjectListModel<Item>*");
// I have also tried to add items from here, but the result is even worse
// for(int i = 0; i < 20; i++){
// addItem(QString::number(i));
// }
}
QQmlObjectListModel<Item>* itemsModel(){
return mItemsModel;
}
Q_INVOKABLE void addItem(QString const &name){
Item* item = new Item(mItemsModel);
item->setName(name);
mItemsModel->append(item);
}
private:
QQmlObjectListModel<Item>* mItemsModel;
};
Then in qml:
import QtQuick 2.12
import QtQuick.Controls 2.5
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Scroll")
ScrollView {
anchors.fill: parent
ListView {
width: parent.width
// dataManager is a context property set via c++
model: dataManager.itemsModel
populate: Transition {
id: popTrans
SequentialAnimation {
PauseAnimation {
duration: (popTrans.ViewTransition.index -
popTrans.ViewTransition.targetIndexes[0]) * 100
}
NumberAnimation { property: "scale"; from: 0; to: 1 }
}
}
add: Transition {
id: addTrans
SequentialAnimation {
PauseAnimation {
duration: (addTrans.ViewTransition.index -
addTrans.ViewTransition.targetIndexes[0]) * 100
}
NumberAnimation { property: "scale"; from: 0; to: 1 }
}
}
delegate: ItemDelegate {
text: "Item" + name
width: parent.width
}
}
}
Component.onCompleted: {
var p;
for(p=0; p < 20; p++){
dataManager.addItem(p)
}
}
}
The QQmlObjectListModel
is a helper class which I borrowed from here