带有 QtWebChannel 的 folium 弹出窗口 [英] folium popups with QtWebChannel

查看:86
本文介绍了带有 QtWebChannel 的 folium 弹出窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 QtWebEngineView 中显示了 folium 生成的 HTML(用于 Leaflet.js).在弹出窗口中,我有一个带有单击功能的按钮,该按钮应该在 python 中调用一个方法.但我似乎无法让频道工作.我不确定 QtWebChannel 或 JS 是否有问题,或者可能是 folium?

I am displaying a folium generated HTML(for leaflet.js) in a QtWebEngineView. In the popups I have a button w/ an on-click function that's supposed to call a method back in python. But I cant seem to get the channel to work. I'm not sure if I'm doing something wrong with the QtWebChannel or the JS, or could it be folium?

我已经将以下 javascript 注入到 QWebChannel.js 的末尾,它在 <body>

I've injected the following javascript to end of QWebChannel.js, which loads at the end of the <body>

    var jshelper;
    new QWebChannel(qt.webChannelTransport, function (channel) {
        jshelper = channel.objects.jshelper;
    });

    document.getElementById("myBtn").addEventListener("click", function(){
        jshelper.pathSelected("Test!")
    });

这是我的 Python 代码

Here's my Python Code

import sys
import os

import branca
from branca.element import *

import folium
from folium import plugins

from PyQt5 import QtWebEngineWidgets, QtCore, QtWidgets, QtWebChannel
from PyQt5.QtWidgets import QMainWindow, QAction, QMenu, QApplication, QWidget, QLineEdit, QLabel, QPushButton, QGridLayout, QDockWidget


class Example(QMainWindow):

    def __init__(self):
        super().__init__()

        self.setObjectName('Main')
        QtCore.QMetaObject.connectSlotsByName(self)

        self.view = QtWebEngineWidgets.QWebEngineView()
        self.view.setObjectName('MapWidget')

        self.window  = QWidget()
        self.window.setObjectName('MainWidget')
        self.layout = QGridLayout()
        self.window.setLayout(self.layout)
        self.layout.addWidget(self.view)
        self.setCentralWidget(self.window);

        self.channel = QtWebChannel.QWebChannel(self.view.page())
        self.view.page().setWebChannel(self.channel)
        self.channel.registerObject("jshelper", self)

        self.us = folium.Map(location=[36,-108],
                    zoom_start=5, tiles='StamenWatercolor')
        fastestRoute = folium.PolyLine( ((40,-110), (50,-110)),
                    weight=5,color='blue').add_to(self.us)
        f = Figure()
        f.html.add_child(Element('<button id="myBtn">Try it</button>'))
        f.html.add_child(Element('<p>\n TEST \n</p>'))
        link = JavascriptLink('https://rawgit.com/toknowjoyman/qwebch/master/qwebchannel.js')
        f.html.add_child(Element(link.render()))
        print (f.render())
        iframe = branca.element.IFrame(html=f.render(), width=500, height=300)
        popup = folium.Popup(iframe, max_width=500)
        fastestRoute.add_child(popup)
        self.us.save("html/test.html")
        self.view.load(QtCore.QUrl().fromLocalFile(
            os.path.split(os.path.abspath(__file__))[0]+r'/html/test.html'
        ))

        self.setGeometry(100,100,1200,900)
        self.show()

    @QtCore.pyqtSlot(str)
    def pathSelected(self, lat):
      print(lat)

if __name__ == '__main__':
    sys.argv.append("--remote-debugging-port=8000")
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

非常感谢您帮助解决这个问题

Would really appreciate the help in figuring this out

让我知道我是否应该为弹出窗口或 Leaflet.js api 发布 folium 生成的 html

Let me know if I should post the folium generated html for the popup or for the leaflet.js api

推荐答案

qwebchannel.js 你必须把它放在第一位,你是把它注入到弹窗中,你是在 page().

qwebchannel.js you must put it first, and you are injecting it into the popup and you are registering it in the page().

为此,我们创建一个 Figure () 并在标题中添加 qwebchannel.js

To do this we create a Figure () and in the header we add the qwebchannel.js

principal = Figure()
js = JavascriptLink(QUrl.fromLocalFile(self.htmlPath.absoluteFilePath("qwebchannel.js")).toString())
principal.header.add_child(Element(js.render()))

注意:在qwebchannel中不与按钮建立连接,因为它不存在.

Note: In the qwebchannel does not make the connection with the button because it does not exist.

为此,弹出窗口传递了一个新的 javascript,它将调用 popup.js,我将在其中通过他的父窗口访问 jshelper,即主窗口.

for this the popup is passed a new javascript, which will call popup.js, and where I will access jshelper via his parent, the main window.

popup.js

var jshelper = parent.jshelper;

document.getElementById("myBtn").addEventListener("click", function(){
    console.log("okay");
    jshelper.pathSelected("Test!");
});

.py

f = Figure()
f.html.add_child(Element('<button id="myBtn">Try it</button>'))
f.html.add_child(Element('<p>\n TEST \n</p>'))

link = JavascriptLink(QUrl.fromLocalFile(self.htmlPath.absoluteFilePath("popup.js")).toString())
f.html.add_child(Element(link.render()))

您可以在以下链接中找到完整的示例.

这篇关于带有 QtWebChannel 的 folium 弹出窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆