Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. How to substitute a QAbstractItemModel with a QList<double> role with a QML ListModel?

How to substitute a QAbstractItemModel with a QList<double> role with a QML ListModel?

Scheduled Pinned Locked Moved QML and Qt Quick
1 Posts 1 Posters 1.1k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • H Offline
    H Offline
    hmuelner
    wrote on last edited by
    #1

    I have a model derived from QAbstractItemModel. One of the roles ("values") returns a QList<double> which should be interpreted according to the role "type".

    Here is the reduced header file:
    @struct MyRecord
    {
    MyRecord()
    : type()
    , values()
    {
    }
    MyRecord(QString type, const QList<double>& values)
    : type(type)
    , values(values)
    {
    }
    QString type;
    QList<double> values;
    };

    class MyModel : public QAbstractListModel
    {
    Q_OBJECT
    Q_PROPERTY (int count READ rowCount)
    public:
    MyModel();
    virtual ~MyModel();

    virtual int rowCount(const QModelIndex & parent = QModelIndex()) const;
    virtual QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
    virtual Qt::ItemFlags flags(const QModelIndex & index) const;
    
    enum UserRoles { TypeRole = Qt::UserRole, ValuesRole};
    virtual QHash<int, QByteArray> roleNames() const;
    

    public slots:
    void clear();
    void update(int from, int to);
    void load(const std::vector<MyRecord>& records);
    QVariant getRole(int idx, QString rolename) const;

    @

    This is the data method:
    @QVariant MyModel::data( const QModelIndex & index, int role /= Qt::DisplayRole/ ) const
    {
    Q_D(const MyModel);
    if (!index.isValid()) {
    return QVariant();
    }
    int row = index.row();
    auto current = d->records[row];
    if (role == TypeRole) {
    return current.type;
    } else if (role == ValuesRole) {
    return QVariant::fromValue(current.values);
    }
    return QVariant();
    }
    @

    I use this model in a QML canvas:
    @onPaint: {
    var ctx = getContext('2d')
    // iterate over the model's elements
    for (var i = 0; i < myModel.count; i++)
    {
    var type = myModel.getRole(i, "type");
    var values = myModel.getRole(i,"values");
    switch(true) {
    case type === "Line":
    var a = values[0]
    var b = values[1]
    var c = values[2]
    // draw an "infinite" line defined by ax+by+c=0
    // ....
    break
    }
    }
    }
    @

    This works so far, but for testing I would like to substitute this model with a QML ListModel, something like this:
    @ ListModel {
    id: myModel
    function getRole(i, role) {
    return get(i)[role];
    }
    function getValue(i, j)
    {
    var obj = get(i).values;
    for (var item in obj) {
    console.log(JSON.stringify(item));
    }
    }

        ListElement {
            type:"Segment";
            values: [
                ListElement {value: 135}, // start point x
                ListElement {value: -7.63567}, // start point y
                ListElement{value: 130}, // end point x
                ListElement {value: -2.35309} // end point y
            ]
        }
        ListElement {
            type:"ArcSegment";
            values: [
                ListElement {value: 20.5}, // center x
                ListElement {value: 13.553}, // center y
                ListElement{value: 20.5}, // radius
                ListElement {value: 130.319}, // angle1 deg
                ListElement {value: 180}, // angle2 deg
                ListElement {value: 1} // Counterclockwise
            ]
        }
        ListElement {
            type:"Line"; // a*x  + b*x + c = 0
            values: [
                ListElement {value: 0}, // a
                ListElement {value: -20}, //b
                ListElement{value: 300} //c
            ]
        }
        ListElement {
            type:"Angle";
            values: [
                ListElement {value: 30.9543}, // p1 x
                ListElement {value: 11.0152}, // p1 y
                ListElement{value: 21.5405},  // p2 x
                ListElement {value: 10.0152}, // p2 y
                ListElement {value: 31.5405}, // center x
                ListElement {value: 10.0152}  // center y
            ]
        }
        ListElement {
            type:"PolyLine";
            values: [
                ListElement {value: 10.9543}, // p1 x
                ListElement {value: 11.0152}, // p1 y
                ListElement{value: 21.5405},  // p2 x
                ListElement {value: 10.0152}, // p2 y
                ListElement {value: 31.5405}, // p3 x
                ListElement {value: 10.0152}  // p3 y
                ListElement {value: 41.5405}, // p4 x
                ListElement {value: 20.0152}  // p4 y
            ]
        }
    }
    

    @

    BUT: I could not find a way to access the C++ and the QML model in the same way in my Canvas.
    The "type" role was easy, but the variable length "values" role was impossible for me.

    Any ideas?

    Helmut Mülner

    1 Reply Last reply
    0

    • Login

    • Login or register to search.
    • First post
      Last post
    0
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Get Qt Extensions
    • Unsolved