我想使用Qt5 C++在QWebEngineView中通过HTML / CSS / JS显示 map 。
它已经可以用于传单(https://leafletjs.com/):
如您所见,该窗口显示在给定位置带有标记的 map 。
但是,使用wrld(https://github.com/wrld3d/wrld.js)(基于传单的3D map )进行相同的尝试,我只会得到一个黑色窗口:
此外,命令行上还会显示以下错误/警告:
js: Refused to set unsafe header "Content-length"
js: Refused to set unsafe header "Connection"
js: Failed to load qrc://webgl-cdn1.eegeo.com/art_edits/continuous/incremental/us/sf/251/Ground/0/1/1/3/1/2/3/2/1/2/3/1/1/3/Ground.hcff?appinfo=Undefined%1Fb37aeaf9b6cd7eb5bc303d144af98ad0%1F1879%1Fd2cae54f44447344cfb3802d9365c03c3aa35e47%1FUndefined%1FUndefined%1FJavascript%1FUndefined%1FUndefined%1FJavascript: Cross origin requests are only supported for protocol schemes: http, data, chrome, https.
js: Uncaught abort() at Error
at Sa (https://cdn-webgl.wrld3d.com/eegeojs/public/v1879/eeGeoWebGL.jgz:63:124)
at Ra (https://cdn-webgl.wrld3d.com/eegeojs/public/v1879/eeGeoWebGL.jgz:63:22)
at Object.q [as abort] (https://cdn-webgl.wrld3d.com/eegeojs/public/v1879/eeGeoWebGL.jgz:410:102)
at _abort (https://cdn-webgl.wrld3d.com/eegeojs/public/v1879/eeGeoWebGL.jgz:257:368)
at Rh (https://cdn-webgl.wrld3d.com/eegeojs/public/v1879/eeGeoWebGL.jgz:275:40424)
at or (https://cdn-webgl.wrld3d.com/eegeojs/public/v1879/eeGeoWebGL.jgz:275:389787)
at pgc (https://cdn-webgl.wrld3d.com/eegeojs/public/v1879/eeGeoWebGL.jgz:283:389489)
at ogc (https://cdn-webgl.wrld3d.com/eegeojs/public/v1879/eeGeoWebGL.jgz:283:389037)
at ldc (https://cdn-webgl.wrld3d.com/eegeojs/public/v1879/eeGeoWebGL.jgz:283:298507)
at kdc (https://cdn-webgl.wrld3d.com/eegeojs/public/v1879/eeGeoWebGL.jgz:283:296713)
If this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.
据我所知,它与响应头(Access-Control-Allow-Headers)中缺少标签有关,但我无法使其正常工作。我已经尝试通过QWebEngineUrlRequestInterceptor注入(inject)这些 header ,但没有成功。
这是一个最小的“工作”示例:
main.cpp:
#include <QApplication>
#include <QWebEngineView>
int main(int argc, char** argv) {
qputenv("QT_STYLE_OVERRIDE", "Fusion");
QApplication app(argc, argv);
QWebEngineView* mapview = new QWebEngineView();
mapview->load(QUrl("qrc:/map.html"));
mapview->show();
app.exec();
return 0;
}
map.html :(您需要https://www.wrld3d.com/中的api密钥才能使用wrld版本)
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"
integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
crossorigin=""/>
<!-- comment in for the leaflet version -->
<!-- <script src="https://unpkg.com/[email protected]/dist/leaflet.js"
integrity="sha512-GffPMF3RvMeYyc1LWMHtK8EbPv0iNZ8/oTtHPx9/cc2ILxQ+u905qIwdpULaqDkyBKgOaB57QTMg7ztg8Jm2Og=="
crossorigin=""></script> -->
<!-- wrld version -> not working -->
<script src="https://cdn-webgl.wrld3d.com/wrldjs/dist/latest/wrld.js"></script>
</head>
<body>
<div id="mapid" style="width: 95vw; height: 95vh;"></div>
<script type="application/javascript">
// comment in for the leaflet version
// var map = L.map('mapid').setView([51.505, -0.09], 13);
// L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
// maxZoom: 18,
// attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' +
// '<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
// 'Imagery © <a href="http://www.openstreetmap.org/#map=6/51.">OpenStreetMap</a>',
// id: 'mapbox.streets'
// }).addTo(map);
var map = L.Wrld.map("mapid", "PUT_YOUR_API_KEY_HERE");
</script>
</body>
</html>
resources.qrc:
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>map.html</file>
</qresource>
</RCC>
CMakeLists.txt:
project (PROJ LANGUAGES CXX)
cmake_minimum_required (VERSION 3.9)
# set compiler flags for better warnings
add_compile_options(-Wall -Wextra -pedantic)
# set the required c++ standard to c++20
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 11)
# find Qt5
find_package(Qt5 REQUIRED Network WebEngine Widgets WebEngineWidgets)
qt5_add_resources(RCC_SOURCES resources.qrc)
# create executable with main file
add_executable(prog ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp ${RCC_SOURCES})
target_link_libraries(prog Qt5::Widgets Qt5::WebEngine Qt5::Network Qt5::WebEngineWidgets)
要运行该示例,请将所有四个文件放在一个目录中,然后使用cmake / make编译所有内容。
所需的输出应如下所示:
Qt的QWebEngineView是否可以实现?
传单效果很好。
那就是我不知道为什么它也不应该与wrld一起使用的真正原因。
最佳答案
这不是Qt错误,而是wrld.js中指出的this discussion错误。从该转换中可以得出结论,该库仅支持http或https,而不支持其他方案。
因此,解决方案是通过HTTP服务器启动html,有几种选择,但是假设您只想使用Qt,那么我们可以利用以下模块:Qt HTTP server。要安装它,您必须执行以下步骤:
git clone --recursive https://codereview.qt-project.org/qt-labs/qthttpserver
cd qthttpserver
qmake
make
sudo make install
之后,您必须将main.cpp修改为:
#include <QApplication>
#include <QWebEngineView>
#include <QHttpServer>
int main(int argc, char** argv) {
qputenv("QT_STYLE_OVERRIDE", "Fusion");
QApplication app(argc, argv);
QHttpServer httpServer;
httpServer.route("/", []() {
return QHttpServerResponse::fromFile(QStringLiteral(":/map.html"));
});
const auto port = httpServer.listen(QHostAddress::Any);
if (port == -1) {
qDebug() << QStringLiteral("Could not run on http://127.0.0.1:%1/").arg(port);
return 0;
}
QWebEngineView view;
view.load(QUrl(QStringLiteral("http://127.0.0.1:%1/").arg(port)));
view.show();
return app.exec();
}
还有CMakeLists.txt:
project (PROJ LANGUAGES CXX)
cmake_minimum_required (VERSION 3.9)
# set compiler flags for better warnings
add_compile_options(-Wall -Wextra -pedantic)
# set the required c++ standard to c++20
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 11)
# find Qt5
find_package(Qt5 REQUIRED Network WebEngine Widgets WebEngineWidgets HttpServer)
qt5_add_resources(RCC_SOURCES resources.qrc)
# create executable with main file
add_executable(prog ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp ${RCC_SOURCES})
target_link_libraries(prog Qt5::Widgets Qt5::WebEngine Qt5::Network Qt5::WebEngineWidgets Qt5::HttpServer)
导致: