在PyQ中创建和添加MapQuickItem到Map

2024-03-29 12:37:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用PyQt5通过UI文件中的QQuickWidget访问QML代码。我的QML文件创建地图并绘制点。我想从python代码中添加/修改这些点。我可以在python中访问QML中的Map对象,但是PyQt将它和MapQuickItem视为QQuickItems。我不知道如何在python中实际创建一个新的MapQuickItem并将其添加到Map对象中。我尝试使用必需的属性创建一个QQuickItem,然后使用addMapItem方法,但收到以下错误:

TypeError: unable to convert argument 0 of QQuickItem.addMapItem from 'QQuickItem' to 'QDeclarativeGeoMapItemBase*'"

我不知道如何在PyQt中创建一个QDeclarativeGeoMapItemBase对象,也不知道是否应该用另一种方式来创建。在

如您所见,我在正确引用QML文件中的对象时也遇到了一些问题。self.mapself.map.rootObject()给我UI中的QQuickWidget,self.map.rootObject().children()[1]给我QML中的Map对象。我更喜欢使用findChild()通过它们的ID来定位这些项,但一直未能找到。有更好的方法吗?是否应该创建一个Python对象来复制QML文件的结构?在

这是QML的一个示例。我将这个QML文件引用为UI文件中的QQuickWidget。在

 Rectangle {
id:rectangle

Plugin {
    id: osmPlugin
    name: "osm"
}

property variant locationTC: QtPositioning.coordinate(44.951, -93.192)

Map {
    id: map
    anchors.fill: parent
    plugin: osmPlugin
    center: locationTC
    zoomLevel: 10

    MapQuickItem {
        coordinate: QtPositioning.coordinate(44.97104,-93.46055)
        anchorPoint.x: image.width * 0.5
        anchorPoint.y: image.height
        sourceItem:
            Image { id: image; source: "marker.png" }

    }
  }
}

下面是PyQt代码的一个示例,我试图在其中创建MapQuickItem并将其添加到映射中。在

^{pr2}$

我在Windows7上运行一切。PyQt5的开发是在Eclipse中使用PyDev和python3.4(32位)、Qt Creator 5.5中的QML编码和Qt Designer 5.5中的UI完成的。在


Tags: 文件对象代码imageselfiduimap
1条回答
网友
1楼 · 发布于 2024-03-29 12:37:18
<>在希望与QML交互的C++/Python中,最好将一些对象暴露给QML,允许QC++和Python的数据传输到QML,因为后者具有不同的生命周期。在

在本例中,我将创建一个存储数据的模型,通过setContextProperty()将其发送给QML,在QML端使用MapItemView和委托,这样您就可以有很多标记。在

主.py

import os
from PyQt5 import QtCore, QtWidgets, QtQuickWidgets, QtPositioning

class MarkerModel(QtCore.QAbstractListModel):
    PositionRole, SourceRole = range(QtCore.Qt.UserRole, QtCore.Qt.UserRole + 2)

    def __init__(self, parent=None):
        super(MarkerModel, self).__init__(parent)
        self._markers = []

    def rowCount(self, parent=QtCore.QModelIndex()):
        return len(self._markers)

    def data(self, index, role=QtCore.Qt.DisplayRole):
        if 0 <= index.row() < self.rowCount():
            if role == MarkerModel.PositionRole:
                return self._markers[index.row()]["position"]
            elif role == MarkerModel.SourceRole:
                return self._markers[index.row()]["source"]
        return QtCore.QVariant()

    def roleNames(self):
        return {MarkerModel.PositionRole: b"position_marker", MarkerModel.SourceRole: b"source_marker"}

    def appendMarker(self, marker):
        self.beginInsertRows(QtCore.QModelIndex(), self.rowCount(), self.rowCount())
        self._markers.append(marker)
        self.endInsertRows()

class MapWidget(QtQuickWidgets.QQuickWidget):
    def __init__(self, parent=None):
        super(MapWidget, self).__init__(parent,
            resizeMode=QtQuickWidgets.QQuickWidget.SizeRootObjectToView)
        model = MarkerModel(self)
        self.rootContext().setContextProperty("markermodel", model)
        qml_path = os.path.join(os.path.dirname(__file__), "main.qml")
        self.setSource(QtCore.QUrl.fromLocalFile(qml_path))

        positions = [(44.97104,-93.46055), (44.96104,-93.16055)]
        urls = ["http://maps.gstatic.com/mapfiles/ridefinder-images/mm_20_gray.png", 
                "http://maps.gstatic.com/mapfiles/ridefinder-images/mm_20_red.png"]

        for c, u in zip(positions, urls):
            coord = QtPositioning.QGeoCoordinate(*c)
            source = QtCore.QUrl(u)
            model.appendMarker({"position": coord , "source": source})


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MapWidget()
    w.show()
    sys.exit(app.exec_())

主.qml

^{pr2}$

enter image description here

相关问题 更多 >