I've been facing this issue for days without coming to a conclusion, I hope someone could give me some useful hints to solve it.
I'll try to simplify the issue with an example:
- In my C++ code I defined the class MyObjectModel that will act later as a model in the Repeater block in my main ui.qml file. MyObjectModel is visible to the QQmlApplicationEngine.
- MyObjectModel has 2 attributes (lists) : xCoordinatesList and yCoordinatesList. They represent the x and y pixel coordinates of a list of points. I.e. xCoordinatesList = [100, 200], yCoordinatesList = [10, 20] mean logically that I have 2 points with the following pixel coordinates that I want to display on the screen: (100,10), (10,20).
The xCoordinatesList and yCoordinatesList are Roles of my model for the QML engine. This means for instance that in a common .qml file i can clearly print the content of xCoordinatesList by typing:
Component.onCompleted { console.log("x coordinates: ",xCoordinatesList); }
The question is: how can I display at the same time the list of points on the screen?
If I want to display only one dot (so one couple of coordinates) my code works. I really don't know how to extend it to make it print all of them.
In my MainForm.ui.qml I defined a Repeater inside a Rectangle :
Rectangle
{
....
Repeater
{
model: dotModel
delegate:
DotItem
{
id: dotItem;
objectName: "dotItem";
DotPositionOnMap
{
id: dotPositionId;
objectWidth: dotItem.width;
objectHeight: dotItem.height;
}
x: dotPositionId.xPositionOnMap;
y: dotPositionId.yPositionOnMap;
}
}
....
}
I need a Repeater because MyObjectModel which holds the two lists of x and y coordinates can dynamically change over time. dotModel is just a fake model I use for an other purpose. DotItem is my qml Item that identifies the red dot circle image I want to depict on the screen for each couple of elements in xCoordinatesList, yCoordinatesList.
DotItem.ui.qml
import QtQuick 2.4
import QtQuick.Layouts 1.1
Item
{
width: 10
height: 10
opacity: 1
Image
{
id: dotItemImage
anchors.fill: parent
source: "red_dot.png"
}
}
red_dot.png image should be displayed for each point depicted on the screen.
DotPositionOnMap.qml is responsible for computing the right x and y pixel position on the screen.
import QtQuick 2.5
import "calcCurrentPos_script.js" as CurrentPos
Item
{
// Values filled from MainForm.ui.qml
property int objectWidth
property int objectHeight
// Getting current coordinates
// Fetching element 0 from both lists
property real currentx: CurrentPos.getCurrentxPoint(0);
property real currenty: CurrentPos.getCurrentyPoint(0);
// Generating the x and y pixel position on map.
// Toy example
property int xPositionOnMap : currentx-(objectWidth/2);
property int yPositionOnMap : currenty-(objectHeight/2);
}
Where calcCurrentPos_script.js
function getCurrentxPoint(val)
{
return xCoordinatesList[val];
}
function getCurrentyPoint(val)
{
return yCoordinatesList[val];
}
In this way I can only display one dot on the screen since I specify in DotPositionOnMap.qml which point to fetch:
// Fetching element 0 in this case
property real currentx: CurrentPos.getCurrentxPoint(0);
property real currenty: CurrentPos.getCurrentyPoint(0);
I used javascript for this attempt because I thought I could use a for loop to scan all the elements to be displayed, but it didn't work.
Extract of my model
QVariant MyModelObject::data(const QModelIndex& index, int role) const
{
const MyModelObject& object = objects.values().value(index.row());
....
if(role == XRole)
{
QList<TrackPoint> tkrList = object.getList();
QList<QVariant> tkrVariantList;
for(auto track: trackpointList)
{
tkrVariantList.append(track.getPosition().getX());
}
return QVariant(tkrVariantList);
}
else if(role == YRole)
{
QList<TrackPoint> tkrList = object.getList();
QList<QVariant> tkrVariantList;
for(auto track: trackpointList)
{
tkrVariantList.append(track.getPosition().getY());
}
return QVariant(tkrVariantList);
}
}
....
....
QHash<int, QByteArray> MyModelObject::roleNames() const
{
QHash<int, QByteArray> roles;
roles[XRole] = "xCoordinatesList";
roles[YRole] = "yCoordinatesList";
return roles;
}
I truly appreciate any ideas concerning the generalisation of this implementation.
Thank you