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

VS+Qt项目中QWebEngineView加载百度地图API控件空白问题求助

问题:VS+Qt环境下QWebEngineView加载百度地图HTML空白

问题背景

使用Visual Studio 2022 + Qt 6.2.4 msvc2019_64框架开发地图项目,此前已实现多项Qt功能,现需调用百度地图API。

问题详情

已掌握Qt调用百度地图API的基本流程:通过QWebEngineView加载本地HTML,HTML引入百度地图API脚本,用QWebChannel实现Qt与JS通信。但出现以下异常:

  • QWebEngineView控件显示空白,无报错提示;
  • 用Edge单独打开HTML可正常显示地图;
  • 控件加载普通网页正常;
  • 该功能在Qt Creator中可正常运行,移植到VS+Qt项目后无论新增模块还是新建测试工程均显示空白。

相关代码

HTML文件(BDMap.html)

<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<title>CanvasLayer</title>
<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=(已替换为我的密钥)"></script>
<style type="text/css">
body, html,#container {width: 100%;height: 100%;overflow: hidden;margin:0;font-family:"微软雅黑";}
</style>
</head>
<body>
    <div id="container"></div>
</body>
</html>
<script src="qwebchannel.js"></script>
<script type="text/javascript">
window.onload = function() {
  var mp = new BMap.Map("container");
  mp.centerAndZoom(new BMap.Point(113.411968, 23.054905), 10);
  mp.enableScrollWheelZoom();

  // QWebChannel init
  new QWebChannel(qt.webChannelTransport, function(channel) {
    mw = channel.objects.bridge;
  });

  mp.addEventListener("click", function(e) {
    mw.RcvPoint(e.point.lng, e.point.lat);
  });
};

    function SetPoint(lng,lat){
        mp.setCenter(new BMap.Point(lng,lat));
    }
    
</script>

mainwindow.cpp

//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    JSBridge = new bridge(this);
    QWebChannel *channel = new QWebChannel(this);
    channel->registerObject("window",(QObject*)JSBridge);
    ui->MapWidget->page()->setWebChannel(channel);
    ui->MapWidget->page()->load(QUrl("./Baidu_JS/BDMap.html"));
    connect(JSBridge,SIGNAL(DisplayPoint(QString,QString)),this,SLOT(DisplaySlot(QString,QString)));
}

MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::DisplaySlot(QString lng, QString lat)
{
    ui->lineEdit_RcvMsg->setText(lng+","+lat);
}

void MainWindow::on_pushButton_clicked()
{
    QString context = ui->lineEdit_SendMsg->text();
    if(!context.contains(','))
    {
        qDebug()<<"输入格式错误";        //输入格式 经度+纬度,中间以英文逗号‘,’隔开
        return;
    }
    QString lng = context.split(',').at(0);
    QString lat = context.split(',').at(1);

    ui->MapWidget->page()->runJavaScript(QString("SetPoint(%1,%2)").arg(lng).arg(lat));
}

bridge.cpp

//bridge.cpp
#include "bridge.h"

bridge::bridge(QObject *parent) : QObject(parent)
{

}
void bridge::RcvPoint(const QString &lng, const QString &lat)
{
    qDebug()<<lng<<","<<lat;
    emit DisplayPoint(lng,lat);
}

bridge.h

//bridge.h
#ifndef BRIDGE_H
#define BRIDGE_H

#include <QObject>
#include <QDebug>
class bridge : public QObject
{
    Q_OBJECT
public:
    explicit bridge(QObject *parent = 0);

signals:
    void DisplayPoint(const QString &lng,const QString &lat);

public slots:
    void RcvPoint(const QString &lng,const QString &lat);
};

#endif // BRIDGE_H

mainwindow.h

//mainwindow.h
#pragma once
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include<qwebchannel.h>
#include <QWebEngineSettings>
#include <QWebEngineView>
#include <QWebEnginePage>
#include <QWebEngineProfile>
#include <QWebEngineView>
#include "bridge.h"
namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget* parent = 0);
    ~MainWindow();
private slots:
    void DisplaySlot(QString lng, QString lat);
    void on_pushButton_clicked();

private:
    Ui::MainWindow* ui;
    bridge* JSBridge;
};

#endif // MAINWINDOW_H
解决方案

1. 修复QWebChannel对象注册名称不匹配问题

mainwindow.cpp中注册对象时用了"window",但HTML的JS代码中调用的是channel.objects.bridge,名称不匹配会导致JS无法找到C++对象,引发加载异常。修改代码:

// mainwindow.cpp中注册对象的行改为
channel->registerObject("bridge", JSBridge);

2. 确保本地资源路径正确

VS调试时,程序工作目录默认是项目的Debug/Release文件夹,而非源码文件夹,直接用./Baidu_JS/BDMap.html可能找不到文件,可采用以下两种方法:

  • 方法一:用QDir获取程序运行目录,拼接路径:
QString htmlPath = QDir::currentPath() + "/Baidu_JS/BDMap.html";
ui->MapWidget->page()->load(QUrl::fromLocalFile(htmlPath));
  • 方法二:将HTML文件和qwebchannel.js添加到VS项目,右键文件→属性→复制到输出目录→选择“始终复制”。

3. 检查VS中Qt模块配置

确保VS项目已正确添加Qt WebEngine Widgets和Qt WebChannel模块:右键项目→Qt Project Settings→Modules,勾选webenginewidgets和webchannel。

4. 启用QWebEngine调试日志排查错误

添加日志输出,查看加载过程中的隐藏错误:

// 在MainWindow构造函数开头添加
QWebEngineProfile::defaultProfile()->setHttpUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36");
qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--enable-logging --log-level=3");

运行程序后查看控制台输出,定位具体问题。

5. 修复HTML中qwebchannel.js引用路径

qwebchannel.js可从Qt安装目录的Examples/Qt-6.2.4/webchannel/shared文件夹复制到项目目录,HTML中使用相对路径或绝对路径引用该文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 20:42:07