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 a*x+b*y+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?
↧