Viewing maps with PyQt4 QWebView using python 3

时光总嘲笑我的痴心妄想 提交于 2019-12-01 09:14:52

Some time ago I had created a small library to show markers in maps using PyQt and Google Maps or OpenStreetMap, because of your question I added this functionality so you can download the code from this link and try the example: qOSMExample2.py

In this answer I'll show you the most important parts of my code so that you can add custom functionality.

QWebView supports javascript so I used the leaflet library, and this is included in the html as shown below:

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no"/>


    <style type="text/css">
			html { height: 100%; }
			body { height: 100%; margin: 0; padding: 0 }
			#mapid { height: 100% }
    </style>

    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css"
          integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ=="
          crossorigin=""/>

    <script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet.js"
            integrity="sha512-A7vV8IFfih/D732iSSKi20u/ooOfj/AGehOKq0f4vLT1Zr2Y+RX7C+w8A1gaSasGtRUZpF/NZgzSAu4/Gc41Lg=="
            crossorigin=""></script>

    <script type="text/javascript" src="qOSM.js"></script>
</head>
<body onload="initialize()">
<div id="mapid" style="width:100%; height:100%"></div>
</body>
</html>

In addition if we observe I have imported the qOSM.js file that implements the logic of creating, moving the map and the same with the markers.

The other important is to interact python with javascript for it pyqt offers us 2 functions:

void QWebFrame::addToJavaScriptWindowObject(const QString & name, QObject * object)

Make object available under name from within the frame's JavaScript context. The object will be inserted as a child of the frame's window object. [...]

self.page().mainFrame().addToJavaScriptWindowObject("qtWidget", self)

QVariant QWebFrame::evaluateJavaScript(const QString & scriptSource)

Evaluates the JavaScript defined by scriptSource using this frame as context and returns the result of the last executed statement.

def runScript(self, script):
    return self.page().mainFrame().evaluateJavaScript(script)

The first function allows us to embed a python object in js and so we can output signals from js and connect them to python slots. The second is oriented to execute functions of js and receive what returns. In summary the first one serves to obtain answers asynchronously and the second one synchronously.

In the next part I show the js where the functions mentioned above are implemented:

// Where you want to render the map.

var map;

var markers = [];

var LeafIcon;

function initialize() {
    var element = document.getElementById('mapid');

    map = L.map(element);

    L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
        attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(map);

    if (typeof qtWidget !== 'undefined') {

        map.on('dragend', function () {
            center = map.getCenter();
            qtWidget.mapMoved(center.lat, center.lng);
        });

        map.on('click', function (ev) {
            qtWidget.mapClicked(ev.latlng.lat, ev.latlng.lng);
        });

        map.on('dblclick', function (ev) {
            qtWidget.mapDoubleClicked(ev.latlng.lat, ev.latlng.lng);
        });

        map.on('contextmenu', function (ev) {
            qtWidget.mapRightClicked(ev.latlng.lat, ev.latlng.lng);
        });
    }

    LeafIcon = L.Icon.extend({
        options: {
            shadowUrl: 'leaf-shadow.png',
            iconSize: [38, 95],
            shadowSize: [50, 64],
            iconAnchor: [22, 94],
            shadowAnchor: [4, 62],
            popupAnchor: [-3, -76]
        }
    });
}

function osm_setCenter(lat, lng) {
    //console.log(lat);
    map.panTo(new L.LatLng(lat, lng));
}

function osm_getCenter() {
    return map.getCenter();
}

function osm_setZoom(zoom) {
    map.setZoom(zoom);
}

function osm_addMarker(key, latitude, longitude, parameters) {

    if (key in markers) {
        osm_deleteMarker(key);
    }

    if ("icon" in parameters) {

        parameters["icon"] = new L.Icon({
            iconUrl: parameters["icon"],
            iconAnchor: new L.Point(16, 16)
        });
    }

    var marker = L.marker([latitude, longitude], parameters).addTo(map);

    if (typeof qtWidget !== 'undefined') {

        marker.on('dragend', function (event) {
            var marker = event.target;
            qtWidget.markerMoved(key, marker.getLatLng().lat, marker.getLatLng().lng);
        });

        marker.on('click', function (event) {
            var marker = event.target;
            //marker.bindPopup(parameters["title"]);
            qtWidget.markerClicked(key, marker.getLatLng().lat, marker.getLatLng().lng);
        });

        marker.on('dbclick', function (event) {
            var marker = event.target;
            qtWidget.markerClicked(key, marker.getLatLng().lat, marker.getLatLng().lng);
        });

        marker.on('contextmenu', function (event) {
            var marker = event.target;
            qtWidget.markerRightClicked(key, marker.getLatLng().lat, marker.getLatLng().lng);
        });
    }

    markers[key] = marker;
    return key;
}

function osm_deleteMarker(key) {
    map.removeLayer(markers[key]);
    delete markers[key];
}

function osm_moveMarker(key, latitude, longitude) {
    marker = markers[key];
    var newLatLng = new L.LatLng(latitude, longitude);
    marker.setLatLng(newLatLng);
}

function osm_posMarker(key) {
    marker = markers[key];
    return [marker.getLatLng().lat, marker.getLatLng().lng];
}


http://

Output:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!