带有 QtWebChannel 的 folium 弹出窗口
folium popups with QtWebChannel
我正在 QtWebEngineView 中显示生成的 HTML(对于 leaflet.js)。在弹出窗口中,我有一个带有单击功能的按钮,它应该在 python 中调用一个方法。但我似乎无法让频道正常工作。我不确定是我在使用 QtWebChannel 还是 JS 做错了什么,或者它可能是 folium?
我已将以下 javascript 注入到 QWebChannel.js 的末尾,它在 <body>
的末尾加载
var jshelper;
new QWebChannel(qt.webChannelTransport, function (channel) {
jshelper = channel.objects.jshelper;
});
document.getElementById("myBtn").addEventListener("click", function(){
jshelper.pathSelected("Test!")
});
这是我的Python代码
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_())
非常感谢您帮助解决这个问题
让我知道我是否应该 post 为弹出窗口或 leaflet.js api
生成的 folium html
qwebchannel.js
你必须把它放在第一位,你正在将它注入弹出窗口并在 page()
.
中注册它
为此,我们创建一个图 () 并在 header 中添加 qwebchannel.js
principal = Figure()
js = JavascriptLink(QUrl.fromLocalFile(self.htmlPath.absoluteFilePath("qwebchannel.js")).toString())
principal.header.add_child(Element(js.render()))
注意:在qwebchannel中没有与按钮建立连接,因为它不存在。
为此,弹出窗口传递了一个新的 javascript,它将调用 popup.js,我将通过他的 parent、主 window 访问 jshelper。
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()))
您可以在下面的 link.
中找到完整的示例
我正在 QtWebEngineView 中显示生成的 HTML(对于 leaflet.js)。在弹出窗口中,我有一个带有单击功能的按钮,它应该在 python 中调用一个方法。但我似乎无法让频道正常工作。我不确定是我在使用 QtWebChannel 还是 JS 做错了什么,或者它可能是 folium?
我已将以下 javascript 注入到 QWebChannel.js 的末尾,它在 <body>
var jshelper;
new QWebChannel(qt.webChannelTransport, function (channel) {
jshelper = channel.objects.jshelper;
});
document.getElementById("myBtn").addEventListener("click", function(){
jshelper.pathSelected("Test!")
});
这是我的Python代码
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_())
非常感谢您帮助解决这个问题
让我知道我是否应该 post 为弹出窗口或 leaflet.js api
生成的 folium htmlqwebchannel.js
你必须把它放在第一位,你正在将它注入弹出窗口并在 page()
.
为此,我们创建一个图 () 并在 header 中添加 qwebchannel.js
principal = Figure()
js = JavascriptLink(QUrl.fromLocalFile(self.htmlPath.absoluteFilePath("qwebchannel.js")).toString())
principal.header.add_child(Element(js.render()))
注意:在qwebchannel中没有与按钮建立连接,因为它不存在。
为此,弹出窗口传递了一个新的 javascript,它将调用 popup.js,我将通过他的 parent、主 window 访问 jshelper。
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()))
您可以在下面的 link.
中找到完整的示例