gpt4 book ai didi

javascript - 如何将值从 JS 传回 Python

转载 作者:行者123 更新时间:2023-11-30 20:36:42 28 4
gpt4 key购买 nike

我想用 Python 显示一个 2D map ,然后在 Python 代码中用 coursor 的坐标做一些事情。但是,我无法获得 Python 部分的坐标。这是我的代码:

from PyQt5.QtCore import *
from PyQt5.QtGui import *

from PyQt5.QtWebEngineWidgets import *
from PyQt5.QtWidgets import QWidget,QVBoxLayout, QApplication
from PyQt5.QtWebChannel import QWebChannel
import bs4

maphtml = '''

<!DOCTYPE HTML>
<!DOCTYPE HTML>
<html>
<head>
<meta name="robots" content="index, all" />
<script src="qrc:///qtwebchannel/qwebchannel.js"></script>
<title>WebGL Earth API - Side-by-side - Basic Leaflet compatibility</title>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css" />
<script src="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js"></script>
<script src="http://www.webglearth.com/v2/api.js"></script>
<script>
var backend;
new QWebChannel(qt.webChannelTransport, function (channel) {
backend = channel.objects.backend;
});
function init() {
var m = {};

start_(L, 'L');
start_(WE, 'WE');

function start_(API, suffix) {
var mapDiv = 'map' + suffix;
var map = API.map(mapDiv, {
center: [51.505, -0.09],
zoom: 4,
dragging: true,
scrollWheelZoom: true,
proxyHost: 'http://srtm.webglearth.com/cgi-bin/corsproxy.fcgi?url='
});
m[suffix] = map;

//Add baselayer
API.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',{
attribution: '© OpenStreetMap contributors'
}).addTo(map);

//Add TileJSON overlay
var json = {"profile": "mercator", "name": "Grand Canyon USGS", "format": "png", "bounds": [-112.26379395, 35.98245136, -112.10998535, 36.13343831], "minzoom": 10, "version": "1.0.0", "maxzoom": 16, "center": [-112.18688965, 36.057944835, 13], "type": "overlay", "description": "", "basename": "grandcanyon", "tilejson": "2.0.0", "sheme": "xyz", "tiles": ["http://tileserver.maptiler.com/grandcanyon/{z}/{x}/{y}.png"]};
if (API.tileLayerJSON) {
var overlay2 = API.tileLayerJSON(json, map);
} else {
//If not able to display the overlay, at least move to the same location
map.setView([json.center[1], json.center[0]], json.center[2]);
}

//Add simple marker
var marker = API.marker([json.center[1], json.center[0]]).addTo(map);
marker.bindPopup(suffix, 50);
marker.openPopup();

//Print coordinates of the mouse
map.on('mousemove', function(e) {
document.getElementById('coords').innerHTML = e.latlng.lat + ', ' + e.latlng.lng;
backend.print(e.latlng.lat)
});
}

//Synchronize view
m['L'].on('move', function(e) {
var center = m['L'].getCenter();
var zoom = m['L'].getZoom();
m['WE'].setView([center['lat'], center['lng']], zoom);
});
}
</script>
<style>
html, body{padding: 0; margin: 0; overflow: hidden;}
#mapL, #mapWE {position:absolute !important; top: 0; right: 0; bottom: 0; left: 0;
background-color: #fff; position: absolute !important;}
#mapL {right: 0%;}
#mapWE {left: 100%;}
#coords {position: absolute; bottom: 0;}
</style>
</head>
<body onload="javascript:init()">
<div id="mapL"></div>
<div id="mapWE"></div>
<div id="coords"></div>
</body>
</html>
'''

class Browser(QApplication):
def __init__(self):
QApplication.__init__(self, [])
self.window = QWidget()
self.window.setWindowTitle("Serial GPS Emulator");

self.web = QWebEngineView(self.window)

self.web.setHtml(maphtml)
self.layout = QVBoxLayout(self.window)
self.layout.addWidget(self.web)

self.window.show()
self.exec()

Browser()

如果代码保留在一个文件中会很好,但如果完全不可能在一次拆分中完成,那也是可以接受的。我想解决 mny 问题的第一步是从 HTML/JS 部分调用一个函数,因为 backend.print("test") 也不起作用。我还注意到 self.exec() 阻止了其余代码,有没有办法在 map 运行时执行任何其他代码?谢谢!

最佳答案

我没有看到您在代码中的哪个位置传递了后端。

在这种情况下,您必须创建一个可以注入(inject)的 Backend 类,并且对于要调用的方法,它必须是一个插槽,为此您必须使用 pyqtSlot() 设置,它接收的参数取决于您发送的内容,在 e.latlng 的情况下是 QJsonValue。在插槽中,您必须分离必要的部分。

import sys

from PyQt5.QtCore import pyqtSlot, QObject, QJsonValue, pyqtSignal, QTimer
from PyQt5.QtWebChannel import QWebChannel
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWidgets import QApplication

maphtml = '''

<!DOCTYPE HTML>
<!DOCTYPE HTML>
<html>
<head>
<meta name="robots" content="index, all" />
<script src="qrc:///qtwebchannel/qwebchannel.js"></script>
<title>WebGL Earth API - Side-by-side - Basic Leaflet compatibility</title>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css" />
<script src="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js"></script>
<script src="http://www.webglearth.com/v2/api.js"></script>
<script>
var backend;
new QWebChannel(qt.webChannelTransport, function (channel) {
backend = channel.objects.backend;
console.log(backend);
});
function init() {
var m = {};

start_(L, 'L');
start_(WE, 'WE');

function start_(API, suffix) {
var mapDiv = 'map' + suffix;
var map = API.map(mapDiv, {
center: [51.505, -0.09],
zoom: 4,
dragging: true,
scrollWheelZoom: true,
proxyHost: 'http://srtm.webglearth.com/cgi-bin/corsproxy.fcgi?url='
});
m[suffix] = map;

//Add baselayer
API.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',{
attribution: '© OpenStreetMap contributors'
}).addTo(map);

//Add TileJSON overlay
var json = {"profile": "mercator", "name": "Grand Canyon USGS", "format": "png", "bounds": [-112.26379395, 35.98245136, -112.10998535, 36.13343831], "minzoom": 10, "version": "1.0.0", "maxzoom": 16, "center": [-112.18688965, 36.057944835, 13], "type": "overlay", "description": "", "basename": "grandcanyon", "tilejson": "2.0.0", "sheme": "xyz", "tiles": ["http://tileserver.maptiler.com/grandcanyon/{z}/{x}/{y}.png"]};
if (API.tileLayerJSON) {
var overlay2 = API.tileLayerJSON(json, map);
} else {
//If not able to display the overlay, at least move to the same location
map.setView([json.center[1], json.center[0]], json.center[2]);
}

//Add simple marker
var marker = API.marker([json.center[1], json.center[0]]).addTo(map);
marker.bindPopup(suffix, 50);
marker.openPopup();

//Print coordinates of the mouse
map.on('mousemove', function(e) {
document.getElementById('coords').innerHTML = e.latlng.lat + ', ' + e.latlng.lng;
backend.print(e.latlng)
});
}

//Synchronize view
m['L'].on('move', function(e) {
var center = m['L'].getCenter();
var zoom = m['L'].getZoom();
m['WE'].setView([center['lat'], center['lng']], zoom);
});
}
</script>
<style>
html, body{padding: 0; margin: 0; overflow: hidden;}
#mapL, #mapWE {position:absolute !important; top: 0; right: 0; bottom: 0; left: 0;
background-color: #fff; position: absolute !important;}
#mapL {right: 0%;}
#mapWE {left: 100%;}
#coords {position: absolute; bottom: 0;}
</style>
</head>
<body onload="javascript:init()">
<div id="mapL"></div>
<div id="mapWE"></div>
<div id="coords"></div>
</body>
</html>
'''


class Backend(QObject):
positionChanged = pyqtSignal(float, float)

def __init__(self, parent=None):
QObject.__init__(self, parent)
self.position = None, None
self.timer = QTimer(self)
self.timer.setInterval(1000)
self.timer.timeout.connect(self.on_timeout)

@pyqtSlot(QJsonValue)
def print(self, val):
coords = val.toObject()
lat, lng = (coords[key].toDouble() for key in ("lat", "lng"))
self.position = lat, lng
if not self.timer.isActive():
self.timer.start()

def on_timeout(self):
self.positionChanged.emit(*self.position)


def foo(lat, lng):
# this function will be called every second.
print(lat, lng)


if __name__ == '__main__':
app = QApplication(sys.argv)
view = QWebEngineView()
view.setWindowTitle("Serial GPS Emulator");

backend = Backend(view)
backend.positionChanged.connect(foo)
channel = QWebChannel()
channel.registerObject('backend', backend)
view.page().setWebChannel(channel)
view.setHtml(maphtml)
view.show()
sys.exit(app.exec_())

关于javascript - 如何将值从 JS 传回 Python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49760249/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com