QML and QQuickItem with QWidgets
-
I'm trying to get the
mapviewer
QML example application up and running in aQWidgets
application.Having successfully got the
osm
plugin displaying inside aQWidget
, I'm trying to set or get some simple properties of the QML map object.Being very, very new to QML (i.e. adventures only begun yesterday), I'm now a little stuck.
My QML looks like this:
import QtQuick 2.0 import QtLocation 5.9 import QtPositioning 5.8 Rectangle { id: containter; width: parent.width height: parent.height property variant startPoint: QtPositioning.coordinate(53.5, -3.5) Plugin { id: osmPlugin name: "osm" } Map { id: map anchors.fill: parent plugin: osmPlugin zoomLevel: 10 } MouseArea { id: ma property variant coordinate anchors.fill: parent onClicked: { coordinate = map.toCoordinate(Qt.point(mouse.x, mouse.y)) map.center = coordinate map.update() } } function setCenter() { map.center = startPoint map.update() } Component.onCompleted: setCenter() }
And the initialization of the
QQuickView
and otherQWidgets
inMainWindow.cpp
looks like this:m_view = new QQuickView(); QWidget *container = QWidget::createWindowContainer(m_view); m_view->setSource(QUrl("qrc:/test.qml")); // Get the root object QQuickItem *rect = m_view->rootObject(); // Get the map QQuickItem *map = rect->childItems().at(0); // How do I set this property??? //QGeoCoordinate center(0.0, 0.0); //map->setProperty("center", center); ui->centralWidget->setLayout(new QGridLayout()); ui->centralWidget->layout()->addWidget(container);
So far, so good.
The problem now comes when I want to, say, move the
center
location of the map from myQWidgets
application - maybe via a button press or a function. The Qt documentation seems to indicate that I can use thesetProperty
function to do this however:QGeoCoordinate center(0.0, 0.0); map->setProperty("center", center);
Produces an error because there is no conversion between
QGeoCoordinate
andQVariant
.A trick is being missed. Any help would be greatly received!
-
Ok, so a bit more Googling has brought me to the following function:
QVariant::fromValue()
which allows me to pass in aQGeoCoordinate
into thesetProperty
function and this seems to work.The next trick is property retrieval. As an example, the
supportedMapTypes
property in theMap
object returns a list ofMapType
s for the current plugin.I can iterate through the
supportedMapTypes
list in QML:for (var i = 0; i < map.supportedMapTypes.length; i++) { console.log(map.supportedMapTypes[i].name); }
And then in my
QWidgets
application, if I try to get the property:QList<QVariant> types = map->property("supportedMapTypes").toList();
types
is just an empty list. -
Why
QQuickView
+QWidget::createWindowContainer
instead of justQQuickWidget
? -
Ok, so I've sub-classed a
QQuickWidget
and added an instance to theui->centralWidget->layout()
. I've left a non-subclassedQQuickWidget
with the same QML source in the layout for comparison.When I run the application, the non-subclassed
QQuickWidget
renders the QML perfectly but the sub-classed version shows nothing but a white canvas - nothing is showing. -
Agreed on using QQuickWidget instead. As a side note, if you want a mapping API that supports Widgets (and thus won't require you to use classes like this to shoehorn a QML view into a Widgets app), you can check out the ArcGIS Runtime SDK for Qt - https://developers.arcgis.com/qt/