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?