PySide6中MapPolyline模型新增路径后MapView不更新问题
PySide6 MapPolyline模型更新不显示问题
我在PySide6中创建了MapPolyline模型用于在MapView上绘制路径,但将模型设置到rootContext后,添加新路径时MapView不再更新。目前模型仅能绘制第一条折线,后续添加的路径无法显示。
代码片段
Path.py
from PySide6.QtCore import QObject, Signal from PySide6.QtPositioning import QGeoCoordinate class Path(QObject): def __init__(self, path : list[QGeoCoordinate] = None, color : str = None): super(Path, self).__init__() self.path = path self.color = color def __len__(self): return len(self.path) def __iter__(self): return iter(self.path) def addPoint(self, point): self.path.insert(len(self.path), point) def changeColor(self, color): self.color = color def getColor(self): return self.color def getPath(self): return self.path
PathModel.py
from Path import Path from PySide6.QtCore import Qt, QAbstractListModel, QModelIndex, QByteArray, Slot from PySide6.QtPositioning import QGeoCoordinate class PathModel(QAbstractListModel): ColorRole = Qt.UserRole + 1 PathRole = Qt.UserRole + 2 def __init__(self, paths: list[Path] = None): super().__init__() self._paths = paths or [] def data(self, index, role): if not index.isValid(): return None path = self._paths[index.row()] if role == self.ColorRole: return path.getColor() if role == self.PathRole: return path.getPath() return None def rowCount(self, parent=QModelIndex()): return len(self._paths) def roleNames(self): roles = super().roleNames() roles[self.ColorRole] = QByteArray(b'color') roles[self.PathRole] = QByteArray(b'path') return roles @Slot(result=bool) def addPath(self, df, color): self.beginInsertRows(QModelIndex(), self.rowCount(), self.rowCount()) currentPath = [] for i in range(len(df.index)): point = df.iloc[i] currentPath.append(QGeoCoordinate(point['Latitude'], point['Longitude'])) self._paths.append(Path(currentPath, color)) self.endInsertRows() print(f"Paths added: {self._paths}") return True
MapControl.qml
import QtCore import QtLocation import QtPositioning Rectangle { Plugin { id: mapView name: "osm" PluginParameter { name: "osm.mapping.custom.host" value: "https://tile.openstreetmap.org/" } } MapView { id: view anchors.fill: parent map.plugin: mapView map.activeMapType: map.supportedMapTypes[map.supportedMapTypes.length - 1] Repeater { parent: view.map model: pathModel delegate: MapPolyline { line.width: 5 line.color: model.color path: { var pathPoints = model.path; console.log("Path points:", pathPoints); return pathPoints; } } } } }
MainWindow.py
class MainWindow(QMainWindow, Ui_MainWindow): def __init__(self): super().__init__() self.setupUi(self) self.LoadTripsPushButton.clicked.connect(self.LoadDatabase) self.CurrentTripComboBox.currentTextChanged.connect(self.PlotTrip) self.trips = pd.DataFrame() data = {'Latitude': [51.50, 52.52], 'Longitude': [-0.12, 13.40]} df = pd.DataFrame(data) self.pathModel = PathModel() self.pathModel.addPath(df, 'red') self.QuickMapView.rootContext().setContextProperty('pathModel', self.pathModel) self.QuickMapView.setSource("MapControl.qml") data = {'Latitude': [51.50, 52.52], 'Longitude': [48.85, 2.35]} df = pd.DataFrame(data) self.pathModel.addPath(df, 'green')
问题原因及修复方案
核心问题
PathModel中addPath方法的@Slot装饰器参数错误,Qt信号槽机制无法正确识别参数类型,导致模型更新信号无法被QML视图接收。此外Path类未使用Qt属性机制,后续动态修改属性也会出现视图不更新的问题。
修复步骤
修正
addPath的@Slot装饰器
补充参数类型声明,让Qt正确识别槽函数:@Slot(object, str, result=bool) def addPath(self, df, color): self.beginInsertRows(QModelIndex(), self.rowCount(), self.rowCount()) currentPath = [] for _, point in df.iterrows(): currentPath.append(QGeoCoordinate(point['Latitude'], point['Longitude'])) self._paths.append(Path(currentPath, color)) self.endInsertRows() print(f"Paths added: {self._paths}") return True为
Path类添加Qt属性(推荐)
使用Property装饰器实现属性变化通知:from PySide6.QtCore import QObject, Property, Signal from PySide6.QtPositioning import QGeoCoordinate class Path(QObject): pathChanged = Signal() colorChanged = Signal() def __init__(self, path : list[QGeoCoordinate] = None, color : str = None): super().__init__() self._path = path or [] self._color = color or "#000000" def __len__(self): return len(self._path) def __iter__(self): return iter(self._path) def addPoint(self, point): self._path.append(point) self.pathChanged.emit() @Property(str, notify=colorChanged) def color(self): return self._color @color.setter def color(self, color): if self._color != color: self._color = color self.colorChanged.emit() @Property("QVariantList", notify=pathChanged) def path(self): return self._path同步修改
PathModel的data方法:def data(self, index, role): if not index.isValid(): return None path = self._paths[index.row()] if role == self.ColorRole: return path.color if role == self.PathRole: return path.path return None验证修复
修改后重新运行代码,第二条绿色路径会正常显示在MapView上。后续无论在Python还是QML端调用addPath,视图都会自动刷新。
内容的提问来源于stack exchange,提问作者Abobobobus
相关产品推荐
相关产品推荐

