Problem background: I am developing a project in the framework of VS+QT that needs to call the map api. Many functions of the Qt framework have been successfully implemented before this. The compiler version and framework version is Visual Studio 2022,Qt 6.2.4 msvc2019_64
Specific description of the problem: I have learned that the basic working principle of QT calling Baidu map API is as follows:
First, I need to include the
QWebEngineView header
file in my Qt project so I can use this class in my code.Create a
QWebEngineView
instance that will be used to display web content.Use the
load()
function ofQWebEngineView
to load the HTML file. I can useQUrl
to specify a local file path or URL address. In my example, I usedurl("the relative path")
In the HTML file, I need to introduce the script of Baidu Maps API in the
<head>
tag, which will make the functions of the API available when loading.In order for Qt and JavaScript to communicate with each other, I need to use
QWebChannel
for communication bridge. First, create aQWebChannel
instance in my C++ code andregister
a C++ object (JSBridge
in my case) using theregisterObject()
function.In JavaScript code, I need to use the objects property of
QWebChannel
to get C++ objects and perform further interaction.In the JS code, I can use the API functions provided by Baidu Maps to display and operate the map. You can call the RcvPoint function to pass the longitude and latitude information to the C++ object (JSBridge) when you click on the map, so as to realize the data interaction between Qt and JavaScript.
Hope someone who knows why and how to solve this problem will take the time to hit me up! Thank you very much! !
But when I do this, my control doesn't show that it can't find the file or some other error, it's just blank.
When I open the html file alone, I can see the expected page in edge.
When I change the address opened by the control to an ordinary web page address, it can also be opened normally.
This small function was originally cloned on GitHub, but it can be compiled and run normally in QtCreator, and the expected interface is obtained. But when I re-create the same code and the path of the corresponding file in the VS+Qt project, after compiling and running, the control is blank(I originally added this function module to my own VS+Qt project. After debugging for a long time, it still showed blank. I recreated a solution to test this function, and finally found that I got the same failure result).
I suspect it is The reason for the compiler environment, but I have spent too long and too much energy on this problem, and I don't know how to solve it further, so I seek for your help!
JS file
<!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=(be replaced by my key )"></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.cpp
//mainwindow.cpp
#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
Regarding the problem that Baidu map is displayed as blank in QT's QWebEngineView, if you are sure that there is no problem with the configuration and code, you need to pay attention to the VPN problem. Only when the proxy is turned off can the API of Baidu Map be accessed normally. Otherwise it will be blank.