如何解决将数据从自定义PyQt小部件传递到主python文件
我需要在pyqt5应用程序中显示地图。在尝试了多种选择之后,我得出的结论是,使用Leaflet js是我的最佳选择。我在Qt设计器中创建了一个简单的ui,并在index.py
中连接了ui:
import sys
import os.path
from os import environ
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.uic import loadUiType
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
ui,_=loadUiType('user_interface.ui')
def suppress_qt_warnings():
environ["QT_DEVICE_PIXEL_RATIO"] = "0"
environ["QT_AUTO_SCREEN_SCALE_FACTOR"] = "1"
environ["QT_SCREEN_SCALE_FACTORS"] = "1"
environ["QT_SCALE_FACTOR"] = "1"
class MainApp(QMainWindow,ui):
def __init__(self):
QMainWindow.__init__(self)
self.setupUi(self)
def main():
suppress_qt_warnings()
app=QApplication(sys.argv)
QApplication.processEvents()
window = MainApp()
window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
用户界面中有一个名为leafwidget的经过改进的小部件,其中包含以下代码以显示我的小叶地图(leafwidget.py):
import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
from PyQt5.QtWebChannel import QWebChannel
class WebEnginePage(QWebEnginePage):
def javaScriptConsoleMessage(self,level,message,lineNumber,sourceID):
print("javaScriptConsoleMessage: ",sourceID)
class LeafWidget (QWidget):
def __init__(self,parent=None):
QWidget.__init__(self,parent)
self.browser = QWebEngineView()
self.browser.settings().setAttribute(QWebEngineSettings.JavascriptEnabled,True)
self.browser.setPage(WebEnginePage(self.browser))
self.browser.load(QUrl.fromLocalFile(QDir.current().absoluteFilePath('mymap.html')))
self.browser.loadFinished.connect(self.onLoadFinished)
self.channel = QWebChannel()
self.handler = CallHandler()
self.channel.registerObject('jsHelper',self.handler)
self.browser.page().setWebChannel(self.channel)
lay = QVBoxLayout(self)
lay.addWidget(self.browser)
def onLoadFinished(self,ok):
if ok:
self.browser.page().runJavaScript("")
class CallHandler(QObject):
@pyqtSlot(int)
def logMapId(self,ID1):
print('callback received',ID1)
正如您在这段代码中所看到的,我实际上是在加载mymap.html
文件,包括传单地图和一些JavaScript,以样式化并加载geojson文件。这是我的html代码:
<!DOCTYPE html>
<head>
<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="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="qrc:///qtwebchannel/qwebchannel.js"></script>
<script type="text/javascript">
var backend;
new QWebChannel(qt.webChannelTransport,function(channel) {
backend = channel.objects.jsHelper;
})
</script>
<style>
#my-map {
width:1200px;
height:450px;
}
</style>
</head>
<body>
<div id="my-map"></div>
<script>
var osmUrl1 = 'http://{s}.tile.osm.org/{z}/{x}/{y}.png';
var grayscale = L.tileLayer(osmUrl1,{id: 'MapID',attribution:'1'});
var baseMaps = {
"Grayscale": grayscale,};
var myStyle = {
"color": "blue","weight": 4,};
$.getJSON("roadway.geojson",function(data) {
var geojson = L.geoJson(data,{
style: myStyle,onEachFeature: function (feature,layer) {
layer.on('click',function (e) {
backend.logMapId(feature.properties.ID1)
});
},});
var map = L.map('my-map')
.fitBounds(geojson.getBounds());
var overlayMaps = {
"net": geojson
};
grayscale.addTo(map)
geojson.addTo(map);
L.control.layers(baseMaps,overlayMaps).addTo(map);
});
</script>
</body>
</html>
此处要注意的关键点是单击事件,该事件使用QWebChannel
至leafwidget.py
返回geiojson图层的被单击行ID。然后在leafwidget.py
中,我使用CallHandler
类内的一个插槽接收了单击的行ID。一切正常,每次单击一行我都可以在控制台中看到打印的ID值。
现在,最后一步是将每个链接ID传递给我的index.py,然后在 listview
中显示。我正在考虑在CallHandler
类中定义一个信号,并在每次单击地图中的线并在CallHandler
中接收到它时发出线ID。然后在我的index.py的一个插槽中接收发射的值,并将其添加到 listview
中。我不确定该怎么做?
解决方法
这是您完成的一项琐碎的任务:使用信号,因为它们允许您在对象之间异步交换信息。另一方面,模块或.py文件的概念仅在类,函数等的组织中有意义,但它不干预操作本身,因为这发生在对象的交互之间。
class CallHandler(QObject):
geojson_clicked = pyqtSignal(int)
@pyqtSlot(int)
def logMapId(self,ID1):
self.geojson_clicked.emit(ID1)
class MainApp(QMainWindow,ui):
def __init__(self):
QMainWindow.__init__(self)
self.setupUi(self)
self.LeafWidget.handler.geojson_clicked.connect(self.handle_geojson_clicked)
def handle_geojson_clicked(self,id_):
self.statusBar().showMessage("{} clicked".format(id_))
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。