[SOLVED] How to add item to ListView?
-
I have ListView and I want to add new items by timer (for example).
I didn't understand how...
I found only "String ListModel Example":http://doc.qt.nokia.com/4.7-snapshot/declarative-modelviews-stringlistmodel.html and "AbstractItemModel Example":http://doc.qt.nokia.com/4.7-snapshot/declarative-modelviews-abstractitemmodel.html. But it's static filling, not dynamic.Example: every n second add new item to ListView with current time. How can I do this?
Thanks. -
And how to set QStandardItemModel to ListView?
Just like in "AbstractItemModel Example"?I can't understan how to update model: of ListView...
-
just call
@
QStandardItemModel *stdModel = new QStandardItemModel(this);// populate the model here, if you want
listView->setModel(stdModel);
@QStandardItemModel is a subclass of QAbstractItemModel, so you can use it for every item view (not for the item widgets, those do not need a model!). The [[Doc:QStandardItemModel]] has a basic usage example too.
If you want to add new entries to the model, just call the respective methods of QStandardItemModel, like appendRow, insertRow, etc.
-
No, no, no!
I mean QML ListView! :) -
Never mind :)
-
Any ideas how to add items?
-
You can always use insert, append, clear methods of "QML ListModel Element":http://doc.qt.nokia.com/4.7-snapshot/qml-listmodel.html.
-
I know, but I need to get items from QAbstractItemModel or other type of model.
-
Hmm, If you exposed your "QAbstractItemModel":developer.qt.nokia.com/doc/qt-4.7/qabstractitemmodel.html derived model to QML like this
@
QDeclarativeView* iView;
//...
//MyListModel derived from QAbstractItemModel
MyListModel* iListModel;//...
iView->rootContext()->setContextProperty("listModel",iListModel);
@
and set it in qml list like this
@
ListView {
//...
model:listModel
//...
}
@
then every time you insert something to your model you have to call
@
beginInsertRows(QModelIndex(),startPos,endPos);
endInsertRows();
@and your QML ListView will be updated
-
Ok. I set my model to ListView. Thanks.
But how to add new item to this model, for example, after click on MouseArea.
Something like:
@MouseArea {
onClicked: myModel.append("text") // but here I get an error "TypeError: Result of expression 'myModel.append' [undefined] is not a function."
}@ -
You will have to supply slots on your model (or another class that you have also exposed to QML) that provide this functionality. However, because you are using a QAbstractItemModel, we have no idea what kind of model that is, so it is impossible to help you with the details. Are you sure you need to have your model in C++ though? I mean, if you just want to append simple texts, why not use one of the models QML supplies you?
-
Why not to use QML ListModel?
If you really want to do it using model exposed to QML from C++, then as Andre said you have to:
Make method which you call in onClicked a slot
@public slot:
void append(/??/);
@
or declare method as invokable
@
Q_INVOKABLE void append(/??/);
@ -
Thanks. It's works.
bq. Why not to use QML ListModel?
Becouse I need to use list items in my C++ code.
So QML - only GUI, all other works in C++ code. QML only for showing my items.
I think it's correct way, is it? -
In principle, it is, yes. However, best practices are still materializing as Qt Quick is still a young technology. However, this approach: only GUI in Quick, the logic in C++ has been used successfully for real, commercial projects. There was a great presentation on this on the DevDays.
If you need access to your data from the C++ side, then it makes perfect sense to use a QAbstractItemModel to expose your data to the QML side of things. Could you please tell us your final solution, so others may learn from it?
-
I understand. Thanks for explanation.
Here is my code example (all pretty simple):
app.qml
@import QtQuick 1.0Item {
id: item
width: 300; height: 400property int i: 0 Component { id: myDelegate Row { spacing: 10 Text { text: name } } } ListView { x: 0 y: 0 width: 300 height: 350 model: myModel delegate: myDelegate } aRectangle { id: rectangle1 x: 0 y: 350 width: 300 height: 50 color: "#000000" MouseArea { anchors.fill: parent onClicked: myModel.append(i++) } }
}@
main.cpp
@#include <QDeclarativeView>
#include <QDeclarativeContext>
#include <QApplication>
#include "mymodel.h"int main(int argc, char *argv[])
{
QApplication app(argc, argv);QDeclarativeView view; QDeclarativeContext *ctxt = view.rootContext(); ctxt->setContextProperty("myModel", new MyModel); view.setSource(QUrl::fromLocalFile("app.qml")); view.show(); return app.exec();
}@
mymodel.cpp
@#include "mymodel.h"MyModel::MyModel(QObject *parent)
: QAbstractListModel(parent)
{
QHash<int, QByteArray> roles;
roles[NameRole] = "name";
setRoleNames(roles);
}void MyModel::append(const QString &text)
{
beginInsertRows(QModelIndex(), rowCount(), rowCount());
itemList.append(text);
endInsertRows();
}int MyModel::rowCount(const QModelIndex & parent) const
{
return itemList.count();
}QVariant MyModel::data(const QModelIndex & index, int role) const
{
if (index.row() < 0 || index.row() > itemList.count())
return QVariant();
return itemList.at(index.row());
}@
mymodel.h
@#ifndef MYMODEL_H
#define MYMODEL_H#include <QDeclarativeItem>
#include <QAbstractListModel>
#include <QStringList>class MyModel : public QAbstractListModel
{
Q_OBJECTpublic:
MyModel(QObject *parent = 0);enum AnimalRoles {NameRole = Qt::UserRole + 1}; void addItem(const QString &text); int rowCount(const QModelIndex & parent = QModelIndex()) const; QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
public slots:
void append(const QString &text);private:
QStringList itemList;
};
#endif@