I have a Qt app that displays Google Maps in a QWebEngineView. The app runs fine when compiled on Windows 10. However, it fails on macOS.
Here is a portion of the console output showing the error that occurs when I try to run initMap
:
14:32:18.294 Info: listening on localhost:12345 (mainwindow.cpp:198, MainWindow::MainWindow(int, char **, QWidget *))
14:32:18.294 Info: registering webViewBridge (mainwindow.cpp:208, MainWindow::MainWindow(int, char **, QWidget *))
14:32:19.214 Info: progress 0 loading "file:///Users/allenkempe/Projects/mapper/mapper_QT/mapper_app/html/GoogleMaps2.htm" (mainwindow.cpp:4828, auto MyWebEnginePage::MyWebEnginePage(QObject *)::(anonymous class)::operator()(int) const)
14:32:19.406 Info: progress 70 loading "file:///Users/allenkempe/Projects/mapper/mapper_QT/mapper_app/html/GoogleMaps2.htm" (mainwindow.cpp:4828, auto MyWebEnginePage::MyWebEnginePage(QObject *)::(anonymous class)::operator()(int) const)
14:32:19.493 Debug: javaScriptConsoleMessage: "Loading WebChannel.js" at 4 source: "qrc:///WebChannel.js" (mainwindow.h:74, virtual void MyWebEnginePage::javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel, const QString &, int, const QString &))
14:32:19.498 Debug: javaScriptConsoleMessage: "Loading GoogleMaps.js" at 24 source: "qrc:///GoogleMaps.js" (mainwindow.h:74, virtual void MyWebEnginePage::javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel, const QString &, int, const QString &))
14:32:19.498 Debug: javaScriptConsoleMessage: "GoogleMaps.js line 58!" at 74 source: "qrc:///GoogleMaps.js" (mainwindow.h:74, virtual void MyWebEnginePage::javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel, const QString &, int, const QString &))
14:32:19.498 Debug: javaScriptConsoleMessage: "GoogleMaps.js loaded!" at 2771 source: "qrc:///GoogleMaps.js" (mainwindow.h:74, virtual void MyWebEnginePage::javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel, const QString &, int, const QString &))
14:32:19.498 Debug: javaScriptConsoleMessage: "Connecting to WebSocket server at ws://localhost:12345." at 13 source: "qrc:///WebChannel.js" (mainwindow.h:74, virtual void MyWebEnginePage::javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel, const QString &, int, const QString &))
14:32:19.534 Info: progress 80 loading "file:///Users/allenkempe/Projects/mapper/mapper_QT/mapper_app/html/GoogleMaps2.htm" (mainwindow.cpp:4828, auto MyWebEnginePage::MyWebEnginePage(QObject *)::(anonymous class)::operator()(int) const)
14:32:19.534 Info: progress 100 loading "file:///Users/allenkempe/Projects/mapper/mapper_QT/mapper_app/html/GoogleMaps2.htm" (mainwindow.cpp:4828, auto MyWebEnginePage::MyWebEnginePage(QObject *)::(anonymous class)::operator()(int) const)
14:32:19.970 Info: new connection to browser (mainwindow.cpp:186, auto MainWindow::MainWindow(int, char **, QWidget *)::(anonymous class)::operator()() const)
14:32:19.987 Debug: javaScriptConsoleMessage: "WebSocket connected, setting up QWebChannel." at 30 source: "qrc:///WebChannel.js" (mainwindow.h:74, virtual void MyWebEnginePage::javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel, const QString &, int, const QString &))
14:32:20.040 Debug: javaScriptConsoleMessage: "enter QWebChannel[object Object]" at 32 source: "qrc:///WebChannel.js" (mainwindow.h:74, virtual void MyWebEnginePage::javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel, const QString &, int, const QString &))
14:32:20.040 Debug: javaScriptConsoleMessage: "connect to signals [object Object]" at 39 source: "qrc:///WebChannel.js" (mainwindow.h:74, virtual void MyWebEnginePage::javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel, const QString &, int, const QString &))
14:32:20.041 Debug: javaScriptConsoleMessage: "begin GoogleMaps.js initMap()" at 4 source: "qrc:///initMap.js" (mainwindow.h:74, virtual void MyWebEnginePage::javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel, const QString &, int, const QString &))
14:32:20.041 Debug: "initMap started" (webviewbridge.cpp:293, void WebViewBridge::debug(QString))
14:32:20.042 Debug: javaScriptConsoleMessage: "Uncaught ReferenceError: google is not defined" at 20 source: "qrc:///initMap.js" (mainwindow.h:74, virtual void MyWebEnginePage::javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel, const QString &, int, const QString &))
- QWebchannel is used to set up what I call
webViewBridge
, which allows the C++ app to interface with the JavaScript routines in GoogleMaps.js. - When loading the Google Maps API is finished, the function
onLoad
inWebChannel
is called. After setting up thewebViewBridge
, it callswindow.initialize
inGoogleMaps.js
, which callsinitMap
to set up the Google Maps API.
HTML:
<!DOCTYPE html>
<html >
<head>
<meta name="viewport" content="initial-scale=1.0" user-scalable="yes" />
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
#map { height: 100% }
.menu {
width: 160px;
box-shadow: 3px 3px 5px #888888;
border-style: solid;
border-width: 1px;
border-color: grey;
border-radius: 2px;
background-color: #ffff;
position: fixed;
text-align: center;
display: none;
}
.menu-item {
height: 20px;
background-color: white;
}
</style>
<title>Mapper</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<script type="text/javascript" src="qrc:///qwebchannel.js"> </script>
<!-- API key 3 -->
<!--script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery.googlemap/1.5.1/jquery.googlemap.js"></script-->
<!--script src="gmaps.js"></script-->
<script type="text/javascript" src="qrc:///ExtDraggableObject.js"></script>
<script type="text/javascript" src="qrc:///opacityControl.js"></script>
<script type="text/javascript" src="qrc:///WebChannel.js" > </script>
<script type="text/javascript" src="qrc:///GoogleMaps.js" > </script>
<!--script type="text/javascript" src="qrc:///onLoad.js"> </script-->
<script>
onLoad();
</script>
</head>
<body style="font-family: Arial; border: 0 none;">
<!--The div element for the map -->
<div id="map"></div>
<script src="src/index.js"></script>
<script type="text/javascript" src="qrc:///initMap.js" async defer></script>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?v=weekly&key=APIKEY&callback=onLoad" async defer></script>
<div class="menu" id="menu">
<div class="menu-item"><i class="glyphicon glyphicon-file"></i>Manage files</div>
</div>
</body>
</html>
The API key in my HTML file has been obscured for security reasons.
Also, I should point out that trying to use the new Google Maps API loader procedure also fails, hence reverting to the old method using a callback.
All the HTML code I have presented works fine on Windows. More source files are here Github
Since my original post, I have made changes that have resolved the original problem. Despite my comment earlier that it worked fine under Windows, I found that while Google maps would load, there were numerous javscript errors. I tracked these problems back to the multiple Javascript snippets and the use of using qrc to load resources.
I have now restored all my Javascript code to one file, which includes initMap() as an async function. A small javascript file, apikey.js enables me to specify the api key to use in the html file.
While the original problem seemingly has been resolved, Google Maps now fails in UBUNTU and MACOS with the error "Uncaught (in promise) Error: The Google Maps JavaScript API could not load." However, the GoogleMaps API loads and runs OK on Windows.
14:02:36.932 Info: progress 0 loading "file:///home/allen/Projects/Mapper/mapper/mapper_app/Resources/GoogleMaps2n.htm" (mainwindow.cpp:4875, MyWebEnginePage::MyWebEnginePage(QObject*)::<lambda(int)>)
14:02:37.009 Info: progress 70 loading "file:///home/allen/Projects/Mapper/mapper/mapper_app/Resources/GoogleMaps2n.htm" (mainwindow.cpp:4875, MyWebEnginePage::MyWebEnginePage(QObject*)::<lambda(int)>)
14:02:37.036 Debug: javaScriptConsoleMessage: "Loading WebChannel.js" at 4 source: "file:///home/allen/Projects/Mapper/mapper/mapper_app/Resources/WebChannel.js" (mainwindow.h:74, virtual void MyWebEnginePage::javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel, const QString&, int, const QString&))
14:02:37.041 Debug: javaScriptConsoleMessage: "Loading GoogleMaps.js" at 25 source: "file:///home/allen/Projects/Mapper/mapper/mapper_app/Resources/GoogleMaps.js" (mainwindow.h:74, virtual void MyWebEnginePage::javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel, const QString&, int, const QString&))
14:02:37.041 Debug: javaScriptConsoleMessage: "GoogleMaps.js loaded!" at 2782 source: "file:///home/allen/Projects/Mapper/mapper/mapper_app/Resources/GoogleMaps.js" (mainwindow.h:74, virtual void MyWebEnginePage::javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel, const QString&, int, const QString&))
14:02:37.042 Debug: javaScriptConsoleMessage: "Connecting to WebSocket server at ws://localhost:12345." at 13 source: "file:///home/allen/Projects/Mapper/mapper/mapper_app/Resources/WebChannel.js" (mainwindow.h:74, virtual void MyWebEnginePage::javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel, const QString&, int, const QString&))
14:02:37.043 Debug: javaScriptConsoleMessage: "api keys loaded" at 3 source: "file:///home/allen/Projects/Mapper/mapper/mapper_app/Resources/apikey.js" (mainwindow.h:74, virtual void MyWebEnginePage::javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel, const QString&, int, const QString&))
14:02:37.124 Info: new connection to browser (mainwindow.cpp:4649, MainWindow::setupbridge()::<lambda()>)
14:02:37.125 Info: progress 80 loading "file:///home/allen/Projects/Mapper/mapper/mapper_app/Resources/GoogleMaps2n.htm" (mainwindow.cpp:4875, MyWebEnginePage::MyWebEnginePage(QObject*)::<lambda(int)>)
14:02:37.126 Info: progress 100 loading "file:///home/allen/Projects/Mapper/mapper/mapper_app/Resources/GoogleMaps2n.htm" (mainwindow.cpp:4875, MyWebEnginePage::MyWebEnginePage(QObject*)::<lambda(int)>)
14:02:37.126 Debug: javaScriptConsoleMessage: "WebSocket connected, setting up QWebChannel." at 30 source: "file:///home/allen/Projects/Mapper/mapper/mapper_app/Resources/WebChannel.js" (mainwindow.h:74, virtual void MyWebEnginePage::javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel, const QString&, int, const QString&))
14:02:37.128 Debug: javaScriptConsoleMessage: "enter QWebChannel[object Object]" at 32 source: "file:///home/allen/Projects/Mapper/mapper/mapper_app/Resources/WebChannel.js" (mainwindow.h:74, virtual void MyWebEnginePage::javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel, const QString&, int, const QString&))
14:02:37.129 Debug: javaScriptConsoleMessage: "connect to signals [object Object]" at 39 source: "file:///home/allen/Projects/Mapper/mapper/mapper_app/Resources/WebChannel.js" (mainwindow.h:74, virtual void MyWebEnginePage::javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel, const QString&, int, const QString&))
14:02:37.131 Debug: javaScriptConsoleMessage: "Uncaught (in promise) Error: The Google Maps JavaScript API could not load." at 44 source: "file:///home/allen/Projects/Mapper/mapper/mapper_app/Resources/GoogleMaps2n.htm" (mainwindow.h:74, virtual void MyWebEnginePage::javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel, const QString&, int, const QString&))
In order to resolve the failure of the Google Maps API, I have re-created my apikeys and checked the div element, all possible sources of the problem.
At the time of my original post, I could not get the QWebEngineView to display anything but a gray screen in UBUNTU but found a link that suggested that specifying "CONFIG+=use_gold_linker" in my .pro file would resolve this. That worked, I can now load a URL such as "https"//googlemaps.com" or other web page but not my local html file.
Solved: Loading the html file and the local javascript files as a qrc resources solved the problem. i.e
webView->load(QUrl("qrc:/GoogleMaps.htm"));
resolved the problem.