Создание открытого вида карты улиц

Я пытаюсь перенести этот код: https://gist.github.com/ataffanel/13aac4b79bc0080b881f на самые последние версии pyqt5, таким образом, используя qtwebengine. Цель состоит в том, чтобы в конце концов получить виджет карты.

Это код, который у меня уже есть, работающий со случайным html и javascript, он работал, но я не могу получить представление карты, для которого предназначен исходный код.

Основной.ру:


class MainWindow(QtWidgets.QWidget):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setupUi()
        self.show()
        self.raise_()

    def setupUi(self):
        #self.setFixedSize(800, 500)        
        vbox = QtWidgets.QVBoxLayout()
        self.setLayout(vbox)

        label = self.label = QtWidgets.QLabel()
        sp = QtWidgets.QSizePolicy()
        sp.setVerticalStretch(0)
        label.setSizePolicy(sp)
        vbox.addWidget(label)
        view = self.view = QtWebEngineWidgets.QWebEngineView()  
        channel = self.channel = QWebChannel()

        channel.registerObject('MainWindow', self)
        view.page().setWebChannel(channel)      
      # view.page().mainFrame().addToJavaScriptWindowObject("MainWindow", self)

      # view.page().setLinkDelegationPolicy(QQWebPage.DelegateAllLinks)
        html = open('src/main/assets/map.html','r').read()
        self.view.setHtml(html)
        view.loadFinished.connect(self.onLoadFinished)
        #view.linkClicked.connect(QtWidgets.QDesktopServices.openUrl)

        vbox.addWidget(view)

        button = QtWidgets.QPushButton('Go to Paris')
        panToParis = functools.partial(self.panMap, 2.3272, 48.8620)
        button.clicked.connect(panToParis)
        vbox.addWidget(button)

    def onLoadFinished(self, ok):            
       if ok:   
            page=self.view.page()
            with open('src/main/assets/map.js', 'r') as f:
                src=f.read()
                page.runJavaScript(src)


    @QtCore.pyqtSlot(float, float)
    def onMapMove(self, lat, lng):
        self.label.setText('Lng: {:.5f}, Lat: {:.5f}'.format(lng, lat))

    def panMap(self, lng, lat):
        page=self.view.page()
        page.runJavaScript('map.panTo(L.latLng({}, {}));'.format(lat, lng))

if __name__ == '__main__':
    app = QtWidgets.QApplication([])
    w = MainWindow()

app.exec_()

карта.html:

<!DOCTYPE html>
<html>
<head>
    <script src = "qrc:///qtwebchannel/qwebchannel.js"></script>
    <link rel = "stylesheet" href = "http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />
    <script src = "http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
    <style>
        body { padding: 0; margin: 0; }
        html, body, #map { height: 100%; }
    </style> 
</head>
<body>
    <div id = "map"></div>

</body>
</html>

карта.js:

var map = L.map('map').setView([55.61121, 12.99351], 16);
L.tileLayer('http://otile{s}.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.png', {
    maxZoom: 18,
    attribution: 'Map data &copy; <a href = "http://openstreetmap.org">OpenStreetMap</a> contributors, ' +
        'tiles Courtesy of <a href = "http://www.mapquest.com/" target = "_blank">MapQuest</a>',
    subdomains: '1234',
}).addTo(map);

var marker = L.marker(map.getCenter()).addTo(map);
marker.bindPopup("Hello World!").openPopup();

new QWebChannel(qt.webChannelTransport, function (channel) {
    window.MainWindow = channel.objects.MainWindow;

    if (typeof MainWindow != 'undefined') {
        var onMapMove = function() { MainWindow.onMapMove(map.getCenter().lat, map.getCenter().lng) };
        map.on('move', onMapMove);
        onMapMove();
    }
});

Там нет сообщения об ошибке, просто пустой экран, где должна была быть карта .... Я не понимаю, почему это происходит, поскольку и необходимый javascript, и html рендерятся, если я меняю их на что-то другое ...

Если есть лучший способ создать этот виджет, этого тоже будет достаточно!

Заранее спасибо!

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
0
1 524
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Основная проблема вашего кода заключается в том, что вы используете устаревший шаблон URL и старые версии листовки.

С другой стороны, нет необходимости загружать html и js в виде текста, QtWebEngine может отображать файл напрямую.

Учитывая вышеизложенное, решение такое:

структура:

├── main.py
└── src
    └── main
        └── assets
            ├── map.html
            └── map.js

карта.js

var map;

function initialize(){
    map = L.map('map').setView([55.61121, 12.99351], 16);

    L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        attribution: 'Map data &copy; <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://cloudmade.com">CloudMade</a>',
        maxZoom: 18
    }).addTo(map);

    var marker = L.marker(map.getCenter()).addTo(map);
    marker.bindPopup("Hello World!").openPopup();
    new QWebChannel(qt.webChannelTransport, function (channel) {
        window.MainWindow = channel.objects.MainWindow;
        if (typeof MainWindow != 'undefined') {
            var onMapMove = function() { MainWindow.onMapMove(map.getCenter().lat, map.getCenter().lng) };
            map.on('move', onMapMove);
            onMapMove();
        }
    });
}

карта.html

<!DOCTYPE html>
<html>
<head>
    <script src = "qrc:///qtwebchannel/qwebchannel.js"></script>
    <script src = "https://unpkg.com/[email protected]/dist/leaflet.js"></script>
    <link rel = "stylesheet" href = "https://unpkg.com/[email protected]/dist/leaflet.css" />
    <script type = "text/javascript" src = "map.js"></script>
    <style>
        body { padding: 0; margin: 0; }
        html, body, #map { height: 100%; }
    </style> 
</head>
<body onload = "initialize()">
    <div id = "map"></div>
</body>
</html>

main.py

import os
import functools
from PyQt5 import QtCore, QtGui, QtWidgets, QtWebEngineWidgets, QtWebChannel


class MainWindow(QtWidgets.QWidget):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setupUi()

    def setupUi(self):
        # self.setFixedSize(800, 500)
        vbox = QtWidgets.QVBoxLayout()
        self.setLayout(vbox)

        label = self.label = QtWidgets.QLabel()
        sp = QtWidgets.QSizePolicy()
        sp.setVerticalStretch(0)
        label.setSizePolicy(sp)
        vbox.addWidget(label)
        view = self.view = QtWebEngineWidgets.QWebEngineView()
        channel = self.channel = QtWebChannel.QWebChannel()

        channel.registerObject("MainWindow", self)
        view.page().setWebChannel(channel)

        file = os.path.join(
            os.path.dirname(os.path.realpath(__file__)),
            "src/main/assets/map.html",
        )
        self.view.setUrl(QtCore.QUrl.fromLocalFile(file))

        vbox.addWidget(view)

        button = QtWidgets.QPushButton("Go to Paris")
        panToParis = functools.partial(self.panMap, 2.3272, 48.8620)
        button.clicked.connect(panToParis)
        vbox.addWidget(button)

    @QtCore.pyqtSlot(float, float)
    def onMapMove(self, lat, lng):
        self.label.setText("Lng: {:.5f}, Lat: {:.5f}".format(lng, lat))

    def panMap(self, lng, lat):
        page = self.view.page()
        page.runJavaScript("map.panTo(L.latLng({}, {}));".format(lat, lng))


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

Выход:

Работал как шарм! Спасибо!

mattf 29.05.2019 05:40

Другие вопросы по теме