2017-11-12 41 views
0

PyQt5를 통해 Python으로 GUI를 작성했습니다. Google지도 페이지가있는 웹 브라우저를 보여줍니다. 사용자가 마커를 움직여야하고 내 프로그램이 마커의 좌표를 처리해야합니다. 따라서 JS에서 Python으로 좌표를 전달해야하지만 작동하도록 관리 할 수는 없습니다. 여기 QWebChannel을 사용하여 JS에서 Python으로 정보를 전달하는 방법

은 HTML 파일입니다

<html> 
<head> 
<meta name="viewport" content="initial-scale=1.0, user-scalable=yes" /> 
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> 
<script type="text/javascript"> 

function geocodePosition(pos) { 
    geocoder.geocode({ 
    latLng: pos 
    }, function(responses) { 
    if (responses && responses.length > 0) { 
     updateMarkerAddress(responses[0].formatted_address); 
    } else { 
     updateMarkerAddress('Cannot determine address at this location.'); 
    } 
    }); 
} 

function updateMarkerStatus(str) { 
    document.getElementById('markerStatus').innerHTML = str; 
} 

function updateMarkerPosition(latLng) { 
    document.getElementById('info').innerHTML = [ 
    latLng.lat(), 
    latLng.lng() 
    ].join(', '); 
} 

function updateMarkerAddress(str) { 
    document.getElementById('address').innerHTML = str; 
} 


var geocoder = new google.maps.Geocoder(); 
var map; 


var goldStar = { 
    path: 'M 125,5 155,90 245,90 175,145 200,230 125,180 50,230 75,145 5,90 95,90 z', 
    fillColor: 'yellow', 
    fillOpacity: 0.8, 
    scale: 0.1, 
    strokeColor: 'gold', 
    strokeWeight: 1 
}; 



function addMarker(lat, lon, city, url) { 
    var newmarker = new google.maps.Marker({ 
     position: new google.maps.LatLng(lat, lon), 
     icon: goldStar, 
     map: map, 
     title: city 
    }); 
    newmarker['infowindow'] = new google.maps.InfoWindow({ 
      content: url 
     }); 
    google.maps.event.addListener(newmarker, 'click', function() { 
     this['infowindow'].open(map, this); 
    }); 
} 


function initialize() { 
    var latLng = new google.maps.LatLng(40.767367, -111.848007); 
    // create as a global variable 
    map = new google.maps.Map(document.getElementById('mapCanvas'), { 
    zoom: 11, 
    center: latLng, 
    mapTypeId: google.maps.MapTypeId.ROADMAP 
    }); 
    var marker = new google.maps.Marker({ 
    position: latLng, 
    title: 'Point A', 
    map: map, 
    draggable: true 
    }); 

    // Update current position info. 
    updateMarkerPosition(latLng); 
    geocodePosition(latLng); 

    // Add dragging event listeners. 
    google.maps.event.addListener(marker, 'dragstart', function() { 
    updateMarkerAddress('Dragging...'); 
    }); 

    google.maps.event.addListener(marker, 'drag', function() { 
    updateMarkerStatus('Dragging...'); 
    updateMarkerPosition(marker.getPosition()); 
    }); 

    google.maps.event.addListener(marker, 'dragend', function() { 
    updateMarkerStatus('Drag ended'); 
    geocodePosition(marker.getPosition()); 
    }); 

// return latLng 
} 


// Onload handler to fire off the app. 
google.maps.event.addDomListener(window, 'load', initialize); 

</script> 
</head> 
<body> 
    <style> 
    #mapCanvas { 

    # width: 1000px; 
    width: 102%; 
    height: 500px; 
    float: left; 
    margin-left: -7px; 
    margin-right: -10px; 
    margin-top: -7px; 
    margin-bottom: 10px; 
    } 
    #infoPanel { 
    float: center; 
    margin-left: 20px; 
    } 
    #infoPanel div { 
    margin-bottom: 10px; 
    } 
    </style> 

     <font size="3" color="black" face="verdana"> 
    <div id="mapCanvas"></div> 
    <div id="infoPanel"> 
    <font size="3" color="black" face="verdana"> 
    <!-- <b>Marker status:</b> --> 
    <div id="markerStatus"><i>Click and drag the marker.</i></div> 
    <font size="3" color="black" face="verdana"> 
    <b>Current position:</b> 
    <div id="info"></div> 
    <!--<b>Closest matching address:</b>--> 
    <!--<div id="address"></div>--> 
    </div> 
</body> 
</html> 

그리고 여기 파이썬 코드입니다 : 내가 가장 쉬운 방법은 것 이해

from PyQt5 import QtCore, QtGui, QtWidgets 

class Ui_tmy3page(object): 
    def setupUi(self, MainWindow): 
     MainWindow.setObjectName("MainWindow") 
     MainWindow.resize(900, 620) 
     MainWindow.setMinimumSize(QtCore.QSize(900, 620)) 
     MainWindow.setMaximumSize(QtCore.QSize(900, 620)) 
     MainWindow.setWindowTitle("") 
     self.centralwidget = QtWidgets.QWidget(MainWindow) 
     self.centralwidget.setObjectName("centralwidget") 
     self.html_code = QtWebEngineWidgets.QWebEngineView(self.centralwidget) 
     self.html_code.setGeometry(QtCore.QRect(0, 0, 901, 621)) 
     self.html_code.setUrl(QtCore.QUrl("about:blank")) 
     self.html_code.setObjectName("html_code") 
     MainWindow.setCentralWidget(self.centralwidget) 

     self.retranslateUi(MainWindow) 
     QtCore.QMetaObject.connectSlotsByName(MainWindow) 

    def retranslateUi(self, MainWindow): 
     pass 

from PyQt5 import QtWebEngineWidgets 

: GUI를 코드로

import sys 
from PyQt5.QtWidgets import * 
from GUI_tmy3 import * 

class ShowMap_fun(QMainWindow): 
    def __init__(self): 
     super().__init__() 
     self.map_ui = Ui_tmy3page() # The name of my top level object is MainWindow 
     self.map_ui.setupUi(self) 
     self.map_ui.html_code.load(QtCore.QUrl.fromLocalFile('/Users/carlo/Dropbox/modules_NEW/useless.html')) 


if __name__ == '__main__': 
    app = QApplication(sys.argv) 
    ex = ShowMap_fun() 
    ex.show() 
    sys.exit(app.exec_()) 

QWebChannel을 사용합니다. 예 : here을 찾았지만 제 경우에는 그것을 적용 할 수 없습니다.

의견이 있으십니까?

답변

1

작업 순서를 좀 더 정돈하기 위해 javascript 코드를 useless.js라는 새 파일로 구분했습니다.

class ShowMap_fun(QMainWindow): 
    def __init__(self): 
     super().__init__() 
     self.map_ui = Ui_tmy3page() # The name of my top level object is MainWindow 
     self.map_ui.setupUi(self) 

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

     self.map_ui.html_code.load(QtCore.QUrl.fromLocalFile(QtCore.QDir.current().filePath("useless.html"))) 

    @QtCore.pyqtSlot(float, float) 
    def markerMoved(self, lat, lng): 
     print(lat, lng) 

는 그런 다음에 qwebchannel.js 파일을 추가해야합니다 : 당신이 무엇을해야

또한이 정보를 수신하는 슬롯을 작성해야합니다 개체를하는 QWebChannel 객체를 생성 페이지에 설정하고 등록입니다 코드에서 .html 중에서

useless.html

<html> 
<head> 
    <meta name="viewport" content="initial-scale=1.0, user-scalable=yes"/> 
    <script type="text/javascript" src="./qwebchannel.js"></script> 
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> 
    <script type="text/javascript" src="useless.js"></script> 
</head> 
[...] 

은 objec을 JS t 얻을 수 있어야합니다

useless.js

var jshelper; 

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

[...] 

google.maps.event.addListener(marker, 'drag', function() { 
    updateMarkerStatus('Dragging...'); 
    updateMarkerPosition(marker.getPosition()); 
    jshelper.markerMoved(marker.position.lat(), marker.position.lng()); 
}); 

완전한 예를 들어 다음과 같은 link에서 예제 @eyllanesc에 대한

+0

감사를 발견 할 수 있습니다! 비슷한 방식으로 JS에서 Python에 액세스 할 수있는 PyQt5.QtCore.pyqtProperty를 만들려고 시도했지만 속성에 "알림 신호가없고 상수가 아니라는 메시지가 계속 표시되므로 HTML의 값 업데이트가 중단됩니다 ! ". 파이썬과 JS 모두에서 쓰고 읽을 수있는 속성을 올바르게 구현하는 방법에 대한 조언이 있습니까? – Jeronimo