是否可以在python中从qml创建MapQuickItems?

时间:2017-09-26 14:56:14

标签: python python-3.x pyqt qml pyqt5

我正在处理PyQt5Qml申请。该应用程序显示2 QLineEdits,2 QPushButton以及从我的Qml提供的地图。该应用程序的一个功能是通过python解析(XML-List)中的标题和坐标,并在地图上的坐标上添加引脚。我现在的问题是它只显示最后一个坐标。我意识到这是因为我只更改Qml中引脚Item的属性而不是创建一个新属性。我的问题是:是否可以在python中创建MapQuickItems

1 个答案:

答案 0 :(得分:0)

正如我评论@derM你只需创建一个模型并将其公开给你的QML,没有PyQt的文档,但我们可以参考C ++文档,因为概念是相似的。作为我在以下模型中创建的示例,其中包含标记的信息,在这种情况下,请考虑标记的位置和颜色。

class MarkerItem(object):
    def __init__(self, position, color=QColor("red")):
        self._position = position
        self._color = color

    def position(self):
        return self._position

    def setPosition(self, value):
        self._position = value

    def color(self):
        return self._color

    def setColor(self, value):
        self._color = value


class MarkerModel(QAbstractListModel):
    PositionRole = Qt.UserRole + 1
    ColorRole = Qt.UserRole + 2

    _roles = {PositionRole: QByteArray(b"markerPosition"), ColorRole: QByteArray(b"markerColor")}

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

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

    def roleNames(self):
        return self._roles

    def data(self, index, role=Qt.DisplayRole):
        if index.row() >= self.rowCount():
            return QVariant()
        marker = self._markers[index.row()]

        if role == MarkerModel.PositionRole:
            return marker.position()

        elif role == MarkerModel.ColorRole:
            return marker.color()

        return QVariant()

    def setData(self, index, value, role=Qt.EditRole):
        if index.isValid():
            marker = self._markers[index.row()]
            if role == MarkerModel.PositionRole:
                marker.setPosition(value)

            if role == MarkerModel.ColorRole:
                marker.setColor(value)

            self.dataChanged.emit(index, index)
            return True
        return QAbstractListModel.setData(self, index, value, role)

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

    def flags(self, index):
        if not index.isValid():
            return Qt.ItemIsEnabled
        return QAbstractListModel.flags(index)|Qt.ItemIsEditable

    def moveRandom(self, ix):
        ind = self.index(ix, 0)
        current_pos = self.data(ind, MarkerModel.PositionRole)
        next_pos = current_pos + 0.002*QPointF(random() - 0.5, random() - 0.5)
        self.setData(ind, next_pos, MarkerModel.PositionRole)
        self.setData(ind, QColor(randint(0, 255), randint(0, 255), randint(0, 255)), MarkerModel.ColorRole)

然后在以下示例中使用:

<强> main.py

if __name__ == "__main__":
    import sys

    QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
    app = QGuiApplication(sys.argv)
    engine = QQmlApplicationEngine()

    model = MarkerModel()
    model.addMarker(MarkerItem(QPointF(-12.0464, -77.0428), QColor("black")))
    model.addMarker(MarkerItem(QPointF(-12.0340, -77.0428), QColor("red")))

    model.addMarker(MarkerItem(QPointF(-12.0440, -77.0280), QColor("#9f5522")))

    context = engine.rootContext()
    context.setContextProperty('markerModel', model)

    engine.load(QUrl.fromLocalFile("main.qml"))

    if len(engine.rootObjects()) == 0:
        sys.exit(-1)

    engine.quit.connect(app.quit)

    timer = QTimer(engine)
    timer.timeout.connect(lambda: model.moveRandom(0))
    timer.start(100)

    sys.exit(app.exec_())

<强> main.qml

import QtQuick 2.0
import QtQuick.Window 2.0
import QtLocation 5.5
import QtPositioning 5.5

Window {
    visible: true
    title: "Python OSM"
    width: 640
    height: 480
    property int marker_size: 16

    Map {
        id: map
        anchors.fill: parent
        plugin: Plugin {
            name: "osm"
        }
        center: QtPositioning.coordinate(-12.0464, -77.0428)
        zoomLevel: 14

        MapItemView {
            model: markerModel
            delegate: MapQuickItem{
                anchorPoint: Qt.point(2.5, 2.5)
                coordinate: QtPositioning.coordinate(markerPosition.x, markerPosition.y)
                zoomLevel: 0
                sourceItem: Rectangle{
                    width:  marker_size
                    height: marker_size
                    radius: marker_size/2
                    border.color: "white"
                    color: markerColor
                    border.width: 1
                }
            }
        }
    }
}

获取下图中显示的内容:

enter image description here

注意:我添加了moveRandom方法,向您展示如何更新标记的位置,正如您将在执行示例时看到标记随机移动

完整示例可在以下link

中找到