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



  • 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?


Log in to reply
 

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