In my Qt5.9 widget application project (Windows), I added a QQuickWidget in the ui and set the source file to a QML file.
My itention is to display open street maps in the QQuickWidget. By clicking a button, the center location of the map should change to specific lat/long coordinates.
The map gets displayed in the QQuickWidget as expected, however, I can't get the location change by button click to work.
I am using this QML file content to display the map:
//================================
// map.qml
//================================
import QtQuick 2.0
import QtQuick.Window 2.0
import QtLocation 5.6
import QtPositioning 5.6
Item {
id: qmlMap
Plugin {
id: osmPlugin
name: "osm"
}
Map {
id: map
anchors.fill: parent
plugin: osmPlugin
center: QtPositioning.coordinate(59.91, 10.75)
zoomLevel: 10
objectName: "mainMap"
MapQuickItem {
id: marker
coordinate {latitude: 59.91
longitude: 10.75}
anchorPoint.x: image.width * 0.5
anchorPoint.y: image.height
sourceItem: Image {
id: image
height: 35
width: 35
source: "geotag.png"
}
function recenter(lat,lng) {
map.clearMapItems();
marker.coordinate.latitude = lat;
marker.coordinate.longitude = lng;
map.addMapItem(marker);
map.center.latitude = lat;
map.center.longitude = lng;
map.update();
}
}
}
}
On application start up, I can see the OSM centered on my specified location and I also can see the marker at the right location.
However, when I click my button to call the function recenter(lat,lng)
from C++, nothing seems to happen (no location change on map visible).
My C++ button code for location change is:
void mapproject::on_btnUpdatePos_clicked()
{
QQmlEngine engine;
QQmlComponent component(&engine, "qrc:/map.qml");
QObject *object = component.create();
QVariant returnedValue;
QVariant pos = QVariant(0);
if(object != NULL){
QMetaObject::invokeMethod(object, "recenter",
Q_RETURN_ARG(QVariant, returnedValue),
Q_ARG(QVariant, pos),
Q_ARG(QVariant, pos));
}
}
Why does the location change not work? Is there a mistake in my QML file or in my C++ code?
Assuming that the QQuickWidget
has been added through Qt Designer and it is called quickWidget
, so you can access it using ui->quickWidget
.
To do a simple search you can set an objectName in the MapQuickItem:
MapQuickItem {
id: marker
objectName: "mapItem"
coordinate {latitude: 59.91
[...]
You should not create a new component, you should use the QQuickWidget
, the first thing is to get the item that shows the QQuickWidget
through the rootObject()
method, then look for the child named mapItem
and invoke the recenter method:
void MainWindow::on_btnUpdatePos_clicked()
{
QQuickItem *item = ui->quickWidget->rootObject();
QObject *object = item->findChild<QObject*>("mapItem");
QVariant posx = QVariant(-12.0464);
QVariant posy = QVariant(-77.0428);
if(object != NULL){
QMetaObject::invokeMethod(object, "recenter",
Q_ARG(QVariant, posx),
Q_ARG(QVariant, posy));
}
}
The complete example can be found in the following link