I'm very new to Qt and have issues passing my Model to my View. My view features a bunch of buttons and a Map with some markers whose latitudes/longitudes come from my Model. Clicking on buttons should update the markers on the map (delete some and/or display new ones).
The problem is : When my model (a QList) gets updated on the C++ side, the QML side doesn't.
(I know this kind of question seems to have already been asked, but after reading the different answers, I can't get a clear view of whether I can get away with a smarter way of calling setContextProperty() or if I have to use things like emit signals and bind properties, which I also can't get a clear view of after reading a little documentation)
The architecture is the following :
A main class with a QApplication instantiation and a MainWindow (MainWindow being a custom QMainWindow class). App gets executed and Window gets shown.
A Mapwidget class (custom QQuickWidget class) with an updateMap() method that :
- Reacts to button clicks on the user interface
- Updates the Model (the QList)
- Uses the setContextProperty() method to pass the updated Model to the View
The MainWindow class has a Mapwidget attribute
Things I have tried so far :
When making a call to setContextProperty() in the Mapwidget Constructor before calling the setSource() method, the Model is taken into consideration. So the syntax I'm using for passing the Model into the View ought to be correct. The problem seems to be that any call to setContextProperty() afterwards (in this case : in the updateMap() method) isn't passed to the QML File.
Calling the setContextProperty() on different levels (Mapwidget class, MainWindow class), the results are the same, it's never taken into account after the application's first launch.
I have tested the Model and know for a fact that it does get updated inside the updateMap() method, it just seems like the update isn't transfered to the QML File.
QML File :
Item {
width: 1200
height: 1000
visible: true
Plugin {
id: osmPlugin
name: "osm"
}
Map {
id: map
anchors.fill: parent
plugin: osmPlugin
center: QtPositioning.coordinate(45.782074, 4.871263)
zoomLevel: 5
MapItemView {
model : myModel
delegate: MapQuickItem {
coordinate:QtPositioning.coordinate(
model.modelData.lat,model.modelData.lon)
sourceItem: Image {
id:image_1
source: <picturePath>
}
anchorPoint.x: image_1.width / 2
anchorPoint.y: image_1.height / 2
}
}
}
Mapwidget Class :
mapwidget::mapwidget(QWidget *parent) : QQuickWidget(parent)
{
this->setSource(QUrl(QStringLiteral("qrc:/main.qml")));
}
void mapwidget::updateMap(QList<QObject *> &data)
{
/**
DO OPERATIONS TO UPDATE data
Each append has the following form :
data.append(new DataObject(someLatitude, someLongitude))
*/
this->rootContext()->setContextProperty("myModel", QVariant::fromValue(data));
}
In the updateMap() method, the QObjects appended to the list are of a custom Class DataObject :
class DataObject : public QObject
{
Q_OBJECT
Q_PROPERTY(double lat READ lat WRITE setLat)
Q_PROPERTY(double lon READ lon WRITE setLon)
public:
explicit DataObject(QObject *parent = nullptr);
DataObject(double latitude, double longitude, QObject *parent =
nullptr);
void setLat(double latitude);
void setLon(double longitude);
double lat() const;
double lon() const;
double d_lat;
double d_lon;
}
Why can't the View see the updated Model even after a call to setContextProperty() ?
Thank you for your help