如何让QML映射流量通过代理,并在程序的其余部分禁用该代理?

时间:2019-03-11 16:05:26

标签: c++ qt proxy qml qtlocation

我有一个使用局域网与某些设备对话的应用程序,以及一个HTTP代理来获取外部任何内容。我想在其中使用地图插件。现在,该地图将需要一个http代理来下载图块。如果我使用http_proxy变量设置了全局Qt代理设置,或者使用QNetworkProxy::setApplicationProxy手动进行了设置,则该映射可以很好地加载,但是其余程序会中断。如果我禁用了代理,则可以与我的设备通话,但看不到地图。我已经尝试使用QQmlNetworkAccessManagerFactory,如示例here中所述,它对于view.qml中定义的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?

1 个答案:

答案 0 :(得分:1)

您必须修改插件的源代码:

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来简化更新,因为它是从here下载的。

然后将端点放置在文件夹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
}