[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.



  • Use of [[Doc:QStandardItemModel]] comes into mind.



  • 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! :)



  • 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 :)



  • Never mind :)



  • Any ideas how to add items?



  • [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.



  • 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.0

    Item {
    id: item
    width: 300; height: 400

    property 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&#40;"app.qml"&#41;&#41;;
    view.show();
    return app.exec&#40;&#41;;
    

    }@
    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_OBJECT

    public:
    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@


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.