QWebEngineView.page().runJavaScript() does not run a JavaScript code correctly

Question:

I am making a Python program using PyQt5 GUI library.
I found out that using runJavaScript() method does not work for executing JavaScript code on my HTML document.

Here is my HTML document – a Mapbox GL JS component. It can also be found here: https://docs.mapbox.com/mapbox-gl-js/example/simple-map/ .

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Display a map on a webpage</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<link href="https://api.mapbox.com/mapbox-gl-js/v2.10.0/mapbox-gl.css" rel="stylesheet">
<script src="https://api.mapbox.com/mapbox-gl-js/v2.10.0/mapbox-gl.js"></script><script src="qrc:///qtwebchannel/qwebchannel.js"></script>
<style>
body { margin: 0; padding: 0; }
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
</style>
</head>
<body>
<div id="map"></div>
<script>
    mapboxgl.accessToken = 'pk.eyJ1IjoidmxhZGlra2lyIiwiYSI6ImNsNno2dnN3cjAxamYzbm4xeDhxa2xuY2oifQ.HhDTHZglHlDNte7XwGZ1Xg';
    const map = new mapboxgl.Map({
        container: 'map', // container ID
        // Choose from Mapbox's core styles, or make your own style with Mapbox Studio
        style: 'mapbox://styles/mapbox/streets-v11', // style URL
        center: [-74.5, 40], // starting position [lng, lat]
        zoom: 9, // starting zoom
        projection: 'globe' // display the map as a 3D globe
    });

    map.on('style.load', () => {
        map.setFog({}); // Set the default atmosphere style
    });
</script>

</body>
</html>

Here is a part of my Python code:

# Creating QWebEngineView widget called "mapView"
self.mapView = QtWebEngineWidgets.a
mapSizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
mapSizePolicy.setHeightForWidth(self.mapView.sizePolicy().hasHeightForWidth())
self.mapView.setSizePolicy(mapSizePolicy)
self.mapView.setObjectName("mapView")
self.detstartpointMapLayout.addWidget(self.mapView)

# Opening an HTML document and passing the components to QWebEngineView widget
with open('mapboxjs.html', 'r') as file:
    mapHTML = file.read()
self.mapView.setHtml(mapHTML)
# Running a JavaScript code (with no success).
self.mapView.page().runJavaScript("const marker1 = new mapboxgl.Marker().setLngLat([12.554729, 55.70651]).addTo(map);")

Here is an error that my program returned:

js: Uncaught ReferenceError: mapboxgl is not defined .

I suppose this happens because runJavaScript() or QWebEngineView do not notice libraries that I have imported before in HEAD section of the HTML document using tag. How to I bypass that?
The same JavaScript command works with no errors when I open the HTML code in Firefox and send JS code into the console.

Asked By: Mineges

||

Answers:

My suggestion was right – it happened because the JS function in page.runJavaScript() was executed before the .js script in HEAD section of the HTML file has completed it’s execution.
So, to solve the issue I delayed page().runJavascript() execution until the HTML file finishes loading completely (including .js file in the HEAD section) by replacing

self.widgetname.page().runJavaScript("someJavaScriptFunction")

with

self.widgetname.page().loadFinished.connect(lambda: self.widgetname.page().runJavaScript("someJavaScriptFunction"))

Don’t forget to include lambda: before the self.widgetname.page().runJavaScript() .

Answered By: Mineges