You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyQt5中QWebEngineView.runJavaScript执行Mapbox JS报错求助

问题描述

我使用PyQt5开发Python程序时,调用runJavaScript()方法无法在Mapbox GL JS的HTML文档上正确执行JavaScript代码。

HTML代码

<!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
        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>

Python代码片段

# 创建QWebEngineView组件
self.mapView = QtWebEngineWidgets.QWebEngineView()
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)

# 读取HTML并加载到组件
with open('mapboxjs.html', 'r') as file:
    mapHTML = file.read()
self.mapView.setHtml(mapHTML)
# 执行JavaScript代码(失败)
self.mapView.page().runJavaScript("const marker1 = new mapboxgl.Marker().setLngLat([12.554729, 55.70651]).addTo(map);")

错误信息

js: Uncaught ReferenceError: mapboxgl is not defined .

注:这段JavaScript代码在Firefox控制台执行正常,推测是runJavaScript()或QWebEngineView未识别到HTML头部通过<script>标签导入的库。


解决方案

核心问题是调用runJavaScript()的时机过早,此时HTML中的Mapbox JS库还未加载完成,页面也未初始化完毕。浏览器中能正常执行是因为手动操作时页面已完全加载,而PyQt中直接调用会跳过加载等待阶段。

方法一:监听页面加载完成信号

利用QWebEngineView的loadFinished信号,等页面完全加载后再执行JavaScript代码:

# 替换原runJavaScript调用,绑定加载完成信号
self.mapView.loadFinished.connect(self.on_map_loaded)

def on_map_loaded(self, success):
    if success:
        # 页面加载成功后执行目标JS
        js_code = "const marker1 = new mapboxgl.Marker().setLngLat([12.554729, 55.70651]).addTo(map);"
        self.mapView.page().runJavaScript(js_code)

方法二:通过Qt WebChannel实现回调交互

适合复杂场景的交互需求,通过HTML主动通知Python地图初始化完成:

  1. 修改HTML代码,添加WebChannel逻辑:
<script>
    mapboxgl.accessToken = 'pk.eyJ1IjoidmxhZGlra2lyIiwiYSI6ImNsNno2dnN3cjAxamYzbm4xeDhxa2xuY2oifQ.HhDTHZglHlDNte7XwGZ1Xg';
    const map = new mapboxgl.Map({
        container: 'map',
        style: 'mapbox://styles/mapbox/streets-v11',
        center: [-74.5, 40],
        zoom: 9,
        projection: 'globe'
    });

    map.on('style.load', () => {
        map.setFog({});
        // 地图初始化完成后通知Python端
        new QWebChannel(qt.webChannelTransport, function(channel) {
            window.pyObj = channel.objects.pyObj;
            pyObj.mapReady();
        });
    });
</script>
  1. Python端创建通信对象并绑定信号:
from PyQt5.QtWebChannel import QWebChannel
from PyQt5.QtCore import QObject, pyqtSignal

class MapBridge(QObject):
    mapReady = pyqtSignal()

# 在初始化mapView的代码中添加:
self.bridge = MapBridge()
channel = QWebChannel()
channel.registerObject("pyObj", self.bridge)
self.mapView.page().setWebChannel(channel)

# 绑定地图就绪信号
self.bridge.mapReady.connect(self.on_map_ready)

def on_map_ready(self):
    js_code = "const marker1 = new mapboxgl.Marker().setLngLat([12.554729, 55.70651]).addTo(map);"
    self.mapView.page().runJavaScript(js_code)

额外注意事项

  • 原Python代码中self.mapView = QtWebEngineWidgets.a是笔误,正确写法为QtWebEngineWidgets.QWebEngineView(),已在示例中修正。
  • 使用setHtml()加载本地HTML时,需确保网络连接正常,以加载Mapbox的外部资源。

内容的提问来源于stack exchange,提问作者Mineges

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 00:50:20