[SOLVED] How to add item to ListView?
-
wrote on 5 Nov 2011, 00:34 last edited by
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. -
wrote on 5 Nov 2011, 01:18 last edited by
Use of [[Doc:QStandardItemModel]] comes into mind.
-
wrote on 5 Nov 2011, 11:40 last edited by
And how to set QStandardItemModel to ListView?
Just like in "AbstractItemModel Example"?I can't understan how to update model: of ListView...
-
wrote on 5 Nov 2011, 12:19 last edited by
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.
-
wrote on 5 Nov 2011, 12:24 last edited by
No, no, no!
I mean QML ListView! :) -
wrote on 5 Nov 2011, 12:26 last edited by
OMG - I completely missed that this is in the Qt Quick forums. I should have more coffee before posting weird stuff :-) - sorry for the confusion :)
-
wrote on 5 Nov 2011, 12:31 last edited by
Never mind :)
-
wrote on 5 Nov 2011, 15:42 last edited by
Any ideas how to add items?
-
wrote on 5 Nov 2011, 19:06 last edited by
[quote author="RazrFalcon" date="1320507752"]Any ideas how to add items?[/quote]
Sorry, I don't have much experience with Qt Quick/QML so far - but I'm pretty sure someone else is able to help you.
-
wrote on 6 Nov 2011, 09:51 last edited by
You can always use insert, append, clear methods of "QML ListModel Element":http://doc.qt.nokia.com/4.7-snapshot/qml-listmodel.html.
-
wrote on 6 Nov 2011, 11:24 last edited by
I know, but I need to get items from QAbstractItemModel or other type of model.
-
wrote on 6 Nov 2011, 16:16 last edited by
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
-
wrote on 6 Nov 2011, 16:37 last edited by
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."
}@ -
wrote on 7 Nov 2011, 06:46 last edited by
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?
-
wrote on 7 Nov 2011, 08:36 last edited by
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(/??/);
@ -
wrote on 7 Nov 2011, 13:53 last edited by
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? -
wrote on 7 Nov 2011, 14:06 last edited by
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?
-
wrote on 7 Nov 2011, 16:59 last edited by
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@
1/18