c++ - 如何让 QML 地图流量通过代理,并为程序的其余部分禁用此代理?
问题描述
我有一个使用本地网络与某些设备通信的应用程序,以及一个用于获取外部任何内容的 http 代理。我想在其中使用地图插件。现在地图需要一个 http 代理来下载图块。如果我使用 http_proxy 变量设置全局 Qt 代理设置,或者手动使用,QNetworkProxy::setApplicationProxy
则地图加载正常,但程序的其余部分会中断。如果我禁用代理,那么我可以与我的设备交谈,但我看不到地图。我已经尝试使用,如此处QQmlNetworkAccessManagerFactory
示例中所述,它适用 于view.qml中定义的类型对象, 但如果我用包含我的地图的 an 替换它,它就不起作用 。Image
Image
Item
Item{
width: 500
height: 500
Map {
Plugin {
id: mapPlugin
name: "osm"
}
anchors.fill: parent
plugin: mapPlugin
center: QtPositioning.coordinate(59.91, 10.75)
zoomLevel: 14
visible: true
}
}
该MyNetworkAccessManagerFactory::create
方法永远不会被调用,并且我收到以下错误:
QGeoTileRequestManager: Failed to fetch tile (17366,9541,15) 5 times, giving up. Last error message was: 'Error transferring http://c.tile.openstreetmap.org/15/17366/9541.png - server replied: Service Unavailable'
. 这可能是什么原因?以及如何为地图插件设置 QNetworkProxy?
解决方案
您必须修改插件的源代码:
src/plugins/geoservices/osm/qgeocodingmanagerengineosm.cpp
src/plugins/geoservices/osm/qgeoroutingmanagerengineosm.cpp
src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.cpp
src/plugins/geoservices/osm/qplacemanagerengineosm.cpp
每个文件中都有一个 QNetworkAccessManager,因此您必须添加以下代码:
#include <QtNetwork/QNetworkProxy>
// ...
// constructor
QString proxy = parameters.value(QStringLiteral("proxy")).toString();
if (!proxy.isEmpty()) {
#ifndef QT_NO_NETWORKPROXY
if (proxy.toLower() != QStringLiteral("system")) {
QUrl proxyUrl(proxy);
if (proxyUrl.isValid()) {
qDebug() << "Setting proxy to " << proxyUrl.toString();
m_networkManager->setProxy(
QNetworkProxy(QNetworkProxy::HttpProxy,
proxyUrl.host(),
proxyUrl.port(8080),
proxyUrl.userName(),
proxyUrl.password()));
}
} else if (QNetworkProxy::applicationProxy().type() == QNetworkProxy::NoProxy) {
QNetworkProxyFactory::setUseSystemConfiguration(true);
qDebug() << "Setting system proxy.";
}
#else
qDebug() << "No proxy support";
#endif
} else {
qDebug() << "No proxy parameter specified.";
}
我创建了一个 .patch 来简化更新,因为它可以从这里下载。
然后将两端放在文件夹src/plugins/geoservices/osm
中,应用补丁,编译并安装以下内容:
git clone -b 5.12.1 git@github.com:qt/qtlocation.git
cd qtlocation/src/plugins/geoservices/osm
wget https://raw.githubusercontent.com/eyllanesc/stackoverflow/master/questions/55105933/proxy-osm.patch
git apply proxy-osm.patch
qmake
make
sudo make install
然后,您可以使用插件参数使用代理:
Map {
Plugin {
id: mapPlugin
name: "osm"
PluginParameter { name: "proxy"; value: "http://179.179.253.147:8080" } // <---
}
anchors.fill: parent
plugin: mapPlugin
center: QtPositioning.coordinate(59.91, 10.75)
zoomLevel: 14
visible: true
}
推荐阅读
- c++ - 为什么在这种情况下删除祖父母的构造函数?
- excel - Excel 数据透视表“不同计数”与日期组不兼容?
- php - URL字符串比较在php中不起作用
- php - 如何将php正则表达式输出与switch函数中的字符串进行比较?
- asp.net-mvc - Asp.Net MVC 如何发送更新的模型来查看?
- node.js - Node JS Express 调用多个 API 并返回单个响应
- php - PHP fputcsv 上的换行符
- ibm-watson - 在 Watson Assistant 中重用实体会导致自动填充上下文变量
- terraform - 排除 terraform 模块源中的文件
- html - 我应该给 div 一个非常具体的类名,然后用类选择器或非常通用的名称选择它,然后用后代选择器选择它