如何在pyqt5中创建小部件以显示谷歌地图

迈赫迪帕拉斯塔

如何从用户获取纬度和经度并在 pyqt5 小部件的地图上显示此位置?

我的操作系统是 Windows,我找到了这个链接:

https://github.com/eyllanesc/qMap

但是运行的时候,出现这个错误:

ModuleNotFoundError: No module named 'PyQt5.QtWebKit'

总之,如何在pyqt5中创建小部件来显示谷歌地图?

埃利亚内斯克

QtWebkit 从 Qt 5.6 被弃用,被 Qt WebEngine 取代,PyQt 也是如此,它会产生错误。另一方面,我的库使用 Qt Webkit 实现它,我还没有时间为 PyQt 实现它,但今天我已经完成了(它没有经过全面测试)。

作为观察,谷歌地图目前需要一个 API KEY,您可以按照本指南获取该课程还提供了获取地名的位置,但您还必须使用其他指南启用它

为了让您进行快速测试,我将提供一个 API KEY,但我会随时禁用它。

主文件

import json

from PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets, QtWebChannel, QtNetwork

HTML = '''
<!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
        }
        #map_canvas {
            height: 100%
        }
    </style>
    <script type="text/javascript" src="qrc:///qtwebchannel/qwebchannel.js"></script>
    <script async defer
            src="https://maps.googleapis.com/maps/api/js?key=API_KEY"
            type="text/javascript"></script>
    <script type="text/javascript" src="qgmap.js"></script>
</head>
<body onload="initialize()">
<div id="map_canvas" style="width:100%; height:100%"></div>
</body>
</html>
'''

JS = '''
// main var
var map;
var markers = [];
var qtWidget;

// main init function
function initialize() {
    var myOptions = {
        center: {lat: -34.397, lng: 150.644},
        zoom: 8
    };

    map = new google.maps.Map(document.getElementById('map_canvas'),
        myOptions);

    new QWebChannel(qt.webChannelTransport, function (channel) {
        qtWidget = channel.objects.qGoogleMap;
    });

    google.maps.event.addListener(map, 'dragend', function () {
        var center = map.getCenter();
        qtWidget.mapIsMoved(center.lat(), center.lng());
    });
    google.maps.event.addListener(map, 'click', function (ev) {
        qtWidget.mapIsClicked(ev.latLng.lat(), ev.latLng.lng());
    });
    google.maps.event.addListener(map, 'rightclick', function (ev) {
        qtWidget.mapIsRightClicked(ev.latLng.lat(), ev.latLng.lng());
    });
    google.maps.event.addListener(map, 'dblclick', function (ev) {
        qtWidget.mapIsDoubleClicked(ev.latLng.lat(), ev.latLng.lng());
    });
}
// custom functions
function gmap_setCenter(lat, lng) {
    map.setCenter(new google.maps.LatLng(lat, lng));
}
function gmap_getCenter() {
    return [map.getCenter().lat(), map.getCenter().lng()];
}
function gmap_setZoom(zoom) {
    map.setZoom(zoom);
}
function gmap_addMarker(key, latitude, longitude, parameters) {

    if (key in markers) {
        gmap_deleteMarker(key);
    }
    var coords = new google.maps.LatLng(latitude, longitude);
    parameters['map'] = map
    parameters['position'] = coords;
    var marker = new google.maps.Marker(parameters);
    google.maps.event.addListener(marker, 'dragend', function () {
        qtWidget.markerIsMoved(key, marker.position.lat(), marker.position.lng())
    });
    google.maps.event.addListener(marker, 'click', function () {
        qtWidget.markerIsClicked(key, marker.position.lat(), marker.position.lng())
    });
    google.maps.event.addListener(marker, 'dblclick', function () {
        qtWidget.markerIsDoubleClicked(key, marker.position.lat(), marker.position.lng())
    });
    google.maps.event.addListener(marker, 'rightclick', function () {
        qtWidget.markerIsRightClicked(key, marker.position.lat(), marker.position.lng())
    });
    markers[key] = marker;
    return key;
}
function gmap_moveMarker(key, latitude, longitude) {
    var coords = new google.maps.LatLng(latitude, longitude);
    markers[key].setPosition(coords);
}
function gmap_deleteMarker(key) {
    markers[key].setMap(null);
    delete markers[key]
}
function gmap_changeMarker(key, extras) {
    if (!(key in markers)) {
        return
    }
    markers[key].setOptions(extras);
}
'''


class GeoCoder(QtNetwork.QNetworkAccessManager):
    class NotFoundError(Exception):
        pass

    def geocode(self, location, api_key):
        url = QtCore.QUrl("https://maps.googleapis.com/maps/api/geocode/xml")

        query = QtCore.QUrlQuery()
        query.addQueryItem("key", api_key)
        query.addQueryItem("address", location)
        url.setQuery(query)
        request = QtNetwork.QNetworkRequest(url)
        reply = self.get(request)
        loop = QtCore.QEventLoop()
        reply.finished.connect(loop.quit)
        loop.exec_()
        reply.deleteLater()
        self.deleteLater()
        return self._parseResult(reply)

    def _parseResult(self, reply):
        xml = reply.readAll()
        reader = QtCore.QXmlStreamReader(xml)
        while not reader.atEnd():
            reader.readNext()
            if reader.name() != "geometry": continue
            reader.readNextStartElement()
            if reader.name() != "location": continue
            reader.readNextStartElement()
            if reader.name() != "lat": continue
            latitude = float(reader.readElementText())
            reader.readNextStartElement()
            if reader.name() != "lng": continue
            longitude = float(reader.readElementText())
            return latitude, longitude
        raise GeoCoder.NotFoundError


class QGoogleMap(QtWebEngineWidgets.QWebEngineView):
    mapMoved = QtCore.pyqtSignal(float, float)
    mapClicked = QtCore.pyqtSignal(float, float)
    mapRightClicked = QtCore.pyqtSignal(float, float)
    mapDoubleClicked = QtCore.pyqtSignal(float, float)

    markerMoved = QtCore.pyqtSignal(str, float, float)
    markerClicked = QtCore.pyqtSignal(str, float, float)
    markerDoubleClicked = QtCore.pyqtSignal(str, float, float)
    markerRightClicked = QtCore.pyqtSignal(str, float, float)

    def __init__(self, api_key, parent=None):
        super(QGoogleMap, self).__init__(parent)
        self._api_key = api_key
        channel = QtWebChannel.QWebChannel(self)
        self.page().setWebChannel(channel)
        channel.registerObject("qGoogleMap", self)
        self.page().runJavaScript(JS)

        html = HTML.replace("API_KEY", "YOUR_API_KEY_HERE")
        self.setHtml(html)
        self.loadFinished.connect(self.on_loadFinished)
        self.initialized = False

        self._manager = QtNetwork.QNetworkAccessManager(self)

    @QtCore.pyqtSlot()
    def on_loadFinished(self):
        self.initialized = True

    def waitUntilReady(self):
        if not self.initialized:
            loop = QtCore.QEventLoop()
            self.loadFinished.connect(loop.quit)
            loop.exec_()

    def geocode(self, location):
        return GeoCoder(self).geocode(location, self._api_key)

    def centerAtAddress(self, location):
        try:
            latitude, longitude = self.geocode(location)
        except GeoCoder.NotFoundError:
            print("Not found {}".format(location))
            return None, None
        self.centerAt(latitude, longitude)
        return latitude, longitude

    def addMarkerAtAddress(self, location, **extra):
        if 'title' not in extra:
            extra['title'] = location
        try:
            latitude, longitude = self.geocode(location)
        except GeoCoder.NotFoundError:
            return None
        return self.addMarker(location, latitude, longitude, **extra)

    @QtCore.pyqtSlot(float, float)
    def mapIsMoved(self, lat, lng):
        self.mapMoved.emit(lat, lng)

    @QtCore.pyqtSlot(float, float)
    def mapIsClicked(self, lat, lng):
        self.mapClicked.emit(lat, lng)

    @QtCore.pyqtSlot(float, float)
    def mapIsRightClicked(self, lat, lng):
        self.mapRightClicked.emit(lat, lng)

    @QtCore.pyqtSlot(float, float)
    def mapIsDoubleClicked(self, lat, lng):
        self.mapDoubleClicked.emit(lat, lng)

    # markers
    @QtCore.pyqtSlot(str, float, float)
    def markerIsMoved(self, key, lat, lng):
        self.markerMoved.emit(key, lat, lng)

    @QtCore.pyqtSlot(str, float, float)
    def markerIsClicked(self, key, lat, lng):
        self.markerClicked.emit(key, lat, lng)

    @QtCore.pyqtSlot(str, float, float)
    def markerIsRightClicked(self, key, lat, lng):
        self.markerRightClicked.emit(key, lat, lng)

    @QtCore.pyqtSlot(str, float, float)
    def markerIsDoubleClicked(self, key, lat, lng):
        self.markerDoubleClicked.emit(key, lat, lng)

    def runScript(self, script, callback=None):
        if callback is None:
            self.page().runJavaScript(script)
        else:
            self.page().runJavaScript(script, callback)

    def centerAt(self, latitude, longitude):
        self.runScript("gmap_setCenter({},{})".format(latitude, longitude))

    def center(self):
        self._center = {}
        loop = QtCore.QEventLoop()

        def callback(*args):
            self._center = tuple(args[0])
            loop.quit()

        self.runScript("gmap_getCenter()", callback)
        loop.exec_()
        return self._center

    def setZoom(self, zoom):
        self.runScript("gmap_setZoom({})".format(zoom))

    def addMarker(self, key, latitude, longitude, **extra):
        return self.runScript(
            "gmap_addMarker("
            "key={!r}, "
            "latitude={}, "
            "longitude={}, "
            "{}"
            "); ".format(key, latitude, longitude, json.dumps(extra)))

    def moveMarker(self, key, latitude, longitude):
        return self.runScript(
            "gmap_moveMarker({!r}, {}, {});".format(key, latitude, longitude))

    def setMarkerOptions(self, keys, **extra):
        return self.runScript(
            "gmap_changeMarker("
            "key={!r}, "
            "{}"
            "); "
                .format(keys, json.dumps(extra)))

    def deleteMarker(self, key):
        return self.runScript(
            "gmap_deleteMarker("
            "key={!r} "
            "); ".format(key))


if __name__ == '__main__':
    import sys

    API_KEY = "YOUR_API_KEY_HERE"

    app = QtWidgets.QApplication(sys.argv)
    w = QGoogleMap(api_key=API_KEY)
    w.resize(640, 480)
    w.show()
    w.waitUntilReady()
    w.setZoom(14)
    lat, lng = w.centerAtAddress("Lima Peru")
    if lat is None and lng is None:
        lat, lng = -12.0463731, -77.042754
        w.centerAt(lat, lng)

    w.addMarker("MyDragableMark", lat, lng, **dict(
        icon="http://maps.gstatic.com/mapfiles/ridefinder-images/mm_20_red.png",
        draggable=True,
        title="Move me!"
    ))

    for place in ["Plaza Ramon Castilla", "Plaza San Martin", ]:
        w.addMarkerAtAddress(place, icon="http://maps.gstatic.com/mapfiles/ridefinder-images/mm_20_gray.png")

    w.mapMoved.connect(print)
    w.mapClicked.connect(print)
    w.mapRightClicked.connect(print)
    w.mapDoubleClicked.connect(print)
    sys.exit(app.exec_())

在此处输入图片说明

很快用经过测试的版本更新我的存储库:-)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在PyQt5 GUI中显示Folium地图?

来自分类Dev

如何让 PyQt5 中的小部件填满屏幕?

来自分类Dev

如何在PyQt5的标签小部件中添加堆叠式布局?

来自分类Dev

如何在 PyQT 中定位动态创建的小部件

来自分类Dev

PyQt5 QMainWindow不显示中央小部件

来自分类Dev

布局中的PyQt5 QTreeWidget显示了小部件外部的一列

来自分类Dev

如何在两个 PyQt5 MainWindow 小部件之间切换

来自分类Dev

在pyqt5小部件中更新matplotlib

来自分类Dev

透明框架pyqt5中的透明小部件

来自分类Dev

在PyQt5中对齐弹出窗口小部件

来自分类Dev

在pyqt5小部件中更新matplotlib

来自分类Dev

PyQt5中小部件的动态定位?

来自分类Dev

Python PyQT5 在 mainWindow 中打开小部件

来自分类Dev

在 PyQt5 中更改小部件的高亮颜色

来自分类Dev

在PyQt5中隐藏小部件后,如何设置较小的窗口大小?

来自分类Dev

在PyQt5中删除小部件时如何删除空白

来自分类Dev

PyQT5-如何在QLCD小部件中显示来自串行的发射信号的一部分?

来自分类Dev

Pyqt5 addStretch 在小部件之间?

来自分类Dev

如何在PyQt5 QColorDialog中显示Alpha通道

来自分类Dev

PyQt5 如何在 QLineEdit 中显示按键输入?

来自分类Dev

在PyQt5中找到多个随机创建的小部件(例如QLabel,QPushButton等)的mousepress事件的父级

来自分类Dev

如何使用PyQt5将打开的cv图像(numpy数组)放入主窗口的中央小部件中?

来自分类Dev

PyQt5 - CSV 导入、显示和滚动建议 - 视图与小部件、QTreeView 与其他

来自分类Dev

PyQt5:使用不透明的小部件创建透明窗口

来自分类Dev

如何在PyQt小部件中渲染Altair / Vega

来自分类Dev

在单元测试CI中模拟PyQt5 QMessageBox小部件中的按钮单击

来自分类Dev

PyQt5:如何将子窗口小部件移到主窗口?

来自分类Dev

如何编写Python代码pyqt5在主窗口上附加2个小部件

来自分类Dev

在 PyQt5 中修改 Qgroupbox 的边框颜色而不修改其内部小部件的边框

Related 相关文章

  1. 1

    如何在PyQt5 GUI中显示Folium地图?

  2. 2

    如何让 PyQt5 中的小部件填满屏幕?

  3. 3

    如何在PyQt5的标签小部件中添加堆叠式布局?

  4. 4

    如何在 PyQT 中定位动态创建的小部件

  5. 5

    PyQt5 QMainWindow不显示中央小部件

  6. 6

    布局中的PyQt5 QTreeWidget显示了小部件外部的一列

  7. 7

    如何在两个 PyQt5 MainWindow 小部件之间切换

  8. 8

    在pyqt5小部件中更新matplotlib

  9. 9

    透明框架pyqt5中的透明小部件

  10. 10

    在PyQt5中对齐弹出窗口小部件

  11. 11

    在pyqt5小部件中更新matplotlib

  12. 12

    PyQt5中小部件的动态定位?

  13. 13

    Python PyQT5 在 mainWindow 中打开小部件

  14. 14

    在 PyQt5 中更改小部件的高亮颜色

  15. 15

    在PyQt5中隐藏小部件后,如何设置较小的窗口大小?

  16. 16

    在PyQt5中删除小部件时如何删除空白

  17. 17

    PyQT5-如何在QLCD小部件中显示来自串行的发射信号的一部分?

  18. 18

    Pyqt5 addStretch 在小部件之间?

  19. 19

    如何在PyQt5 QColorDialog中显示Alpha通道

  20. 20

    PyQt5 如何在 QLineEdit 中显示按键输入?

  21. 21

    在PyQt5中找到多个随机创建的小部件(例如QLabel,QPushButton等)的mousepress事件的父级

  22. 22

    如何使用PyQt5将打开的cv图像(numpy数组)放入主窗口的中央小部件中?

  23. 23

    PyQt5 - CSV 导入、显示和滚动建议 - 视图与小部件、QTreeView 与其他

  24. 24

    PyQt5:使用不透明的小部件创建透明窗口

  25. 25

    如何在PyQt小部件中渲染Altair / Vega

  26. 26

    在单元测试CI中模拟PyQt5 QMessageBox小部件中的按钮单击

  27. 27

    PyQt5:如何将子窗口小部件移到主窗口?

  28. 28

    如何编写Python代码pyqt5在主窗口上附加2个小部件

  29. 29

    在 PyQt5 中修改 Qgroupbox 的边框颜色而不修改其内部小部件的边框

热门标签

归档