Using QtLocation Map with QWidget::createWindowContainer() fails to load
-
I am trying to add map functionality to my widget based application. To demonstrate the problem I am having, I will reference the minimal map example.
The QML for drawing the map is in
main.qml
.main.qml
://================================ // main.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 { anchors.fill: parent plugin: osmPlugin center: QtPositioning.coordinate(59.91, 10.75) // Oslo zoomLevel: 10 } }
In order to display this QML as a widget, I create a QQuickView and set its source to
qrc:/main.qml
. Then I get a widget for the QQuickView usingQWidget::createWindowContainer()
. Finally, I add the newly createdQWidget
to a layout in the UI form I designed in Qt Creator. For this simple debugging demo, all it consists of is aQMainWindow
with a singlecentralWidget
, which has a child layout calledqmlLayout
. All this is done inmainwindow.cpp
.mainwindow.cpp
://================================ // mainwindow.cpp //================================ #include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); /* Add the QML map to the UI */ qmlView = new QQuickView(); qmlView->setSource(QUrl(QStringLiteral("qrc:/main.qml"))); qmlView->show(); QWidget *qmlWidget = QWidget::createWindowContainer(qmlView, this); ui->qmlLayout->addWidget(qmlWidget); qmlWidget->show(); } MainWindow::~MainWindow() { delete ui; }
Now, I would expect this to draw a map. Instead, a white screen is drawn
The real kicker, is that if I use the same code but I place it in a
QQuickWidget
, it loads up fine and works perfectly. Unfortunately I can't / don't want to useQQuickWidget
because of its drawbacks. I am doing a lot of OpenGL rendering, and don't want to deal with the loss of threading and performance hits discussed here.Miscellaneous observations I have made:
- The QML is being loaded because if I add a
Rect
to the root QMLItem
it renders properly. But if I place the sameRect
inside theMap
, it is not drawn. - I am receiving no QML errors or warnings aside from issues resolving SSL methods. These same errors appear when the map is functioning properly.
My guesses as to why this isn't working as expected:
Map
only works if it is the child of aWindow
. In order to useQQuickView::setSource()
thought, the root element must be anItem
(unless I am missing something).- Maybe if I try to initialize the
QQuickView
outside ofmain()
the plugin doesn't work.
So... what did I do wrong, or what options do I have?
For completeness, here are the other files involved in the sample project, if you want to replicate the issue on your machine.
qml.qrc
:<RCC> <qresource prefix="/"> <file>main.qml</file> </qresource> </RCC>
main.cpp
://========================= // main.cpp //========================= #include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
mainwindow.h
://======================== // mainwindow.h //======================== #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QQuickView> #include <QQmlEngine> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private: Ui::MainWindow *ui; QQuickView *qmlView; }; #endif // MAINWINDOW_H
mainwindow.ui
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>MainWindow</class> <widget class="QMainWindow" name="MainWindow"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>957</width> <height>636</height> </rect> </property> <property name="windowTitle"> <string>MainWindow</string> </property> <widget class="QWidget" name="centralWidget"> <layout class="QHBoxLayout" name="horizontalLayout"> <item> <layout class="QVBoxLayout" name="qmlLayout"/> </item> </layout> </widget> </widget> <layoutdefault spacing="6" margin="11"/> <resources/> <connections/> </ui>
widgetsMapTest.pro
#============================== # widgetsMapTest.pro #============================== QT += core gui quick location greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = widgetsMapTest TEMPLATE = app DEFINES += QT_DEPRECATED_WARNINGS SOURCES += main.cpp\ mainwindow.cpp HEADERS += mainwindow.h FORMS += mainwindow.ui RESOURCES += \ qml.qrc
TLDR: Inserting a
QQuickView
loaded withQWidget::createWindowContainer()
and then inserting thatQWidget
in to a widget based UI layout results in theQtLocation
Map
type to failing to render. Other QML code executes properly.Thanks for your help =)
- The QML is being loaded because if I add a
-
Another intersting observation, when the map works properly, I receive the following output:
QML debugging is enabled. Only use this in a safe environment. qt.network.ssl: QSslSocket: cannot resolve SSLv2_client_method qt.network.ssl: QSslSocket: cannot resolve SSLv2_server_method QGeoTileProviderOsm: Tileserver disabled at QUrl("http://maps-redirect.qt.io/osm/5.8/satellite") QGeoTileFetcherOsm: all providers resolved
However, when it fails to work properly, I get the following:
QML debugging is enabled. Only use this in a safe environment. qt.network.ssl: QSslSocket: cannot resolve SSLv2_client_method qt.network.ssl: QSslSocket: cannot resolve SSLv2_server_method
And it hangs there, never echoing the message stating that all the providers were resolved. This would make you think that the issue then is some how related to one of the modules listed, but when I switch the plugin to use Mapbox, I get NO console output, and obviously a blank screen.
However, if I add a callback to the
Map
Component.onCompleted
, I can clearly see thatonCompleted
is called for theMap
.The plot thickens.
-
I know this is an old thread but I'm also very interested in the outcome.
I have a QtWidgets application which I'd like to progress to include the features from the
minimal_map
ormapviewer
QML examples. Having never even touched QML before, I haven't even the faintest clue of where to begin.Can Google Maps also be integrated this way, like the OSM maps?
-
@webzoid said in Using QtLocation Map with QWidget::createWindowContainer() fails to load:
this way, like the OSM maps
please have a look at this topic https://forum.qt.io/topic/76730/how-to-integrate-google-maps/24
I managed to used the googlemaps (which is apparently not legit), but I cannot use the satellite view nor use the tilt/bearing map parameters -
@seb21 I've now managed to fully integrate the QML maps into
QWidget
application but I also have a working Google Maps plugin with all map types supported.I can share some code if you like?
I actually prefer the ESRI map implementation over Google Maps and am presently looking at the ArcGIS Runtime SDK stuff for Qt.