Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Help with model for repeater



  • Hi,

    I am trying to make a QML component for drawing x vs y plots. I am drawing the ticks and labels using a repeater in QML:

            Item {
                anchors.fill: parent
                visible: true
                Repeater {
                    model:canvas.xTickPos.length
                    Rectangle{
                        height: 4
                        width: 2
                        x: canvas.xTickPos[index]
                        y: parent.height-height
                        visible: true
                        color: "black"
                        border.width: 2
                    }
                  }
            }
    

    Right now, as a model I am using a javascript array which is a property in the qml file. However, I would like to move the model to the c++ side, and I guess I should do it with a QStandardItemModel or a QAbstractItemModel. The model should contain two variables: tick position (a double) and label (a string). How would you write such a model?



  • Here is a minimal example:

    myitemmodel.h

    #ifndef MYITEMMODEL_H
    #define MYITEMMODEL_H
    
    #include <QAbstractListModel>
    
    struct MyItem{
        double tickPos;
        QString label;
    };
    
    class MyItemModel : public QAbstractListModel
    {
        Q_OBJECT
        enum roles{
            ROLE_TICK_POS = Qt::UserRole + 1,
            ROLE_LABEL,
        };
    public:
        MyItemModel(QObject *parent = nullptr);
    
        // Basic functionality:
        int rowCount(const QModelIndex &parent = QModelIndex()) const override;
        QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
        virtual QHash<int,QByteArray> roleNames() const;
    
        QList<MyItem> items() const;
        void setItems(const QList<MyItem> &items);
    
    private:
        QList<MyItem> m_items;
    
    };
    
    #endif // MyItemModel_H
    
    

    myitemmodel.cpp

    #include "MyItemmodel.h"
    
    MyItemModel::MyItemModel(QObject *parent)
        : QAbstractListModel(parent)
    {
    
    }
    
    int MyItemModel::rowCount(const QModelIndex &parent) const
    {
        if (parent.isValid())
            return 0;
    
        return m_items.count();
    }
    
    QVariant MyItemModel::data(const QModelIndex &index, int role) const
    {
        if (!index.isValid() || index.row() >= m_items.count())
            return QVariant();
    
        MyItem i = m_items.at(index.row());
    
        switch(role){
        case ROLE_TICK_POS: return i.tickPos;
        case ROLE_LABEL: return i.label;
        }
    
        return QVariant();
    }
    
    QHash<int, QByteArray> MyItemModel::roleNames() const
    {
        QHash<int, QByteArray> roles;
        roles[ROLE_TICK_POS] = "role_tickPos";
        roles[ROLE_LABEL] = "role_label";
        return roles;
    }
    
    QList<MyItem> MyItemModel::items() const
    {
        return m_items;
    }
    
    void MyItemModel::setItems(const QList<MyItem> &items)
    {
        beginResetModel();
        m_items = items;
        endResetModel();
    }
    
    

    main.cpp:

    MyItemModel myModel;
    myModel.setItems(...);
    
    QQmlApplicationEngine engine;    
    engine.rootContext()->setContextProperty("myModel", &myModel);
    

    Then in QML:

     Repeater {
            model: myModel
            Rectangle{
                    height: 4
                    width: 2
                    x: role_tickPos  //Use role_label to access label value of the current item
                    y: parent.height-height
                    visible: true
                    color: "black"
                    border.width: 2
            }
    }
    
    • I didn't compile it so it mays have some errors in the code.
    • As I said this is the minimal example but you can then add more features to the model if you need it.
    • Note that the model can also be a property of a QObject instances set as context property in QML engine.


  • Thank you very much!


Log in to reply