从QWebView将javascript变量值导入python
在我的应用程序中,我一边有一个表单,另一边是谷歌地图。为了显示google地图,我使用了他们的javascript api。javascript是作为字符串和html的一部分编写的,该html由QWebView调用。我的目标是让用户点击并拖动pin。在管脚停止拖动后,它将通过qt更新右侧的2个文本框,该文本框将填充放置管脚的纬度和经度。我很难弄清楚如何在javascript和python之间发送数据。我正在使用python3和pyside qt绑定 这是我到目前为止所拥有的从QWebView将javascript变量值导入python,javascript,python-3.x,pyside,Javascript,Python 3.x,Pyside,在我的应用程序中,我一边有一个表单,另一边是谷歌地图。为了显示google地图,我使用了他们的javascript api。javascript是作为字符串和html的一部分编写的,该html由QWebView调用。我的目标是让用户点击并拖动pin。在管脚停止拖动后,它将通过qt更新右侧的2个文本框,该文本框将填充放置管脚的纬度和经度。我很难弄清楚如何在javascript和python之间发送数据。我正在使用python3和pyside qt绑定 这是我到目前为止所拥有的 webView =
webView = QWebView()
webView.setHtml(html)
self.central_widget_grid.addWidget(webView,1,0)
Html是在另一个文件中定义的常量
#!/usr/bin/python
jscode = """
var map;
var marker;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 40.793697, lng: -77.8586},
zoom: 10
});
map.addListener('click', function(e) {
placeMarkerAndPanTo(e.latLng, map);
});
}
function placeMarkerAndPanTo(latLng, map) {
if (marker === undefined) {
marker = new google.maps.Marker({
position: latLng,
map: map,
title: "Station Location",
draggable: true
});
map.panTo(latLng);
marker.addListener('dragend', function() { draggedMarker(); });
}
}
function draggedMarker() {
alert(marker.getPosition());
statLoc.updateLoc(marker.getPosition().lat(), marker.getPosition().lng());
}
"""
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: 0px; padding: 0px }
#map_canvas { height: 100% }
</style>
<script type="text/javascript"
src="http://maps.google.com/maps/api/js?sensor=false&callback=initMap">
</script>
<script type="text/javascript">""" + jscode + """
</script>
</head>
<body onload="initMap();">
<div id="map" style="width:100%; height:100%"></div>
</body>
</html>"""
对我的webView进行以下更改
webView = QWebView()
webView.setHtml(html)
frame = webView.page().mainFrame()
frame.addToJavaScriptWindowObject('statLoc', self.station_location)
self.central_widget_grid.addWidget(webView, 1, 0)
加上这一点。使用StationLocations中的print语句,我希望每次调用该函数时都能看到控制台中打印的纬度和经度。我不明白为什么不是这样 有两件事你做错了。首先,您需要等待页面加载后再添加对象。其次,javascript必须只调用被修饰为插槽的添加对象的方法 下面是一个工作演示。但有一点需要注意:addToJavaScriptWindowObject的PySide实现有缺陷。应该可以使用
self
(即主窗口)作为添加的对象,但当我尝试使用PySide时,它会在退出时挂起几秒钟,然后转储核心。出于这个原因,我在演示中使用了一个代理对象——但是对于PyQt,不需要代理
import sys
from PySide import QtCore, QtGui, QtWebKit
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 { width: 100%; height: 100% }
</style>
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script type="text/javascript">
var map, marker
function initialize() {
map = new google.maps.Map(document.getElementById("map"), {
center: {lat: 40.793697, lng: -77.8586},
zoom: 10
})
marker = new google.maps.Marker({
map: map,
position: map.getCenter(),
draggable: true
})
marker.addListener("dragend", function () {
var pos = marker.getPosition()
qt.showLocation(pos.lat(), pos.lng())
console.log("dragend: " + pos.toString())
})
}
google.maps.event.addDomListener(window, "load", initialize)
</script>
</head>
<body><div id="map"/></body>
</html>
'''
class WebPage(QtWebKit.QWebPage):
def javaScriptConsoleMessage(self, message, line, source):
if source:
print('line(%s) source(%s): %s' % (line, source, message))
else:
print(message)
class Proxy(QtCore.QObject):
@QtCore.Slot(float, float)
def showLocation(self, latitude, longitude):
self.parent().edit.setText('%s, %s' % (latitude, longitude))
class MainWindow(QtGui.QWidget):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.view = QtWebKit.QWebView(self)
self.view.setPage(WebPage(self))
self.edit = QtGui.QLineEdit(self)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.view)
layout.addWidget(self.edit)
self.map = self.view.page().mainFrame()
self.map.loadFinished.connect(self.handleLoadFinished)
self.view.setHtml(html)
self._proxy = Proxy(self)
def handleLoadFinished(self, ok):
self.map.addToJavaScriptWindowObject('qt', self._proxy)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = MainWindow()
window.setGeometry(500, 300, 800, 600)
window.show()
sys.exit(app.exec_())
导入系统
从PySide导入QtCore、QtGui、QtWebKit
html=“”
html{高度:100%}
正文{高度:100%;边距:0;填充:0}
#地图{宽度:100%;高度:100%}
变量映射
函数初始化(){
map=new google.maps.map(document.getElementById(“map”){
中心:{lat:40.793697,lng:-77.8586},
缩放:10
})
marker=新的google.maps.marker({
地图:地图,
位置:map.getCenter(),
德拉格布尔:是的
})
marker.addListener(“dragend”,函数(){
var pos=marker.getPosition()
qt.显示位置(位置lat(),位置lng())
console.log(“dragend:+pos.toString())
})
}
google.maps.event.addDomListener(窗口“加载”,初始化)
'''
班级网页(QtWebKit.QWebPage):
def javaScriptConsoleMessage(自身、消息、行、源):
如果来源:
打印('行(%s)源(%s):%s'(行、源、消息))
其他:
打印(信息)
类代理(QtCore.QObject):
@QtCore.插槽(浮动,浮动)
def显示位置(自身、纬度、经度):
self.parent().edit.setText(“%s,%s%”(纬度,经度))
类主窗口(QtGui.QWidget):
def uuu init uuu(self,parent=None):
超级(主窗口,自我)。\uuuuu初始化\uuuuuuu(父级)
self.view=QtWebKit.QWebView(self)
self.view.setPage(网页(self))
self.edit=QtGui.QLineEdit(self)
layout=QtGui.QVBoxLayout(self)
layout.addWidget(self.view)
layout.addWidget(self.edit)
self.map=self.view.page().mainFrame()
self.map.loadFinished.connect(self.handleLoadFinished)
self.view.setHtml(html)
self.\u proxy=代理(self)
def手动加载完成(自身,正常):
self.map.addToJavaScriptWindowObject('qt',self.\u代理)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
app=QtGui.QApplication(sys.argv)
窗口=主窗口()
窗口设置几何体(500300800600)
window.show()
sys.exit(app.exec_())
import sys
from PySide import QtCore, QtGui, QtWebKit
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 { width: 100%; height: 100% }
</style>
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script type="text/javascript">
var map, marker
function initialize() {
map = new google.maps.Map(document.getElementById("map"), {
center: {lat: 40.793697, lng: -77.8586},
zoom: 10
})
marker = new google.maps.Marker({
map: map,
position: map.getCenter(),
draggable: true
})
marker.addListener("dragend", function () {
var pos = marker.getPosition()
qt.showLocation(pos.lat(), pos.lng())
console.log("dragend: " + pos.toString())
})
}
google.maps.event.addDomListener(window, "load", initialize)
</script>
</head>
<body><div id="map"/></body>
</html>
'''
class WebPage(QtWebKit.QWebPage):
def javaScriptConsoleMessage(self, message, line, source):
if source:
print('line(%s) source(%s): %s' % (line, source, message))
else:
print(message)
class Proxy(QtCore.QObject):
@QtCore.Slot(float, float)
def showLocation(self, latitude, longitude):
self.parent().edit.setText('%s, %s' % (latitude, longitude))
class MainWindow(QtGui.QWidget):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.view = QtWebKit.QWebView(self)
self.view.setPage(WebPage(self))
self.edit = QtGui.QLineEdit(self)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.view)
layout.addWidget(self.edit)
self.map = self.view.page().mainFrame()
self.map.loadFinished.connect(self.handleLoadFinished)
self.view.setHtml(html)
self._proxy = Proxy(self)
def handleLoadFinished(self, ok):
self.map.addToJavaScriptWindowObject('qt', self._proxy)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = MainWindow()
window.setGeometry(500, 300, 800, 600)
window.show()
sys.exit(app.exec_())