Fix garbage collection of ListModelMap items

Prevent ListModel items from being deleted on the C++ side (specially
when using .get() from QML and a new ListModel is created)
by setting their parent to the ListModelMap.
This commit is contained in:
miruka 2019-04-13 09:41:02 -04:00
parent 13fca98838
commit 5c8fd4500d
2 changed files with 10 additions and 4 deletions

View File

@ -5,15 +5,17 @@ from typing import (
from namedlist import namedlist from namedlist import namedlist
from PyQt5.QtCore import ( from PyQt5.QtCore import (
QAbstractListModel, QModelIndex, Qt, pyqtProperty, pyqtSlot QAbstractListModel, QModelIndex, QObject, Qt, pyqtProperty, pyqtSlot
) )
NewValue = Union[Mapping[str, Any], Sequence] NewValue = Union[Mapping[str, Any], Sequence]
class ListModel(QAbstractListModel): class ListModel(QAbstractListModel):
def __init__(self, initial_data: Optional[List[NewValue]] = None) -> None: def __init__(self,
super().__init__() initial_data: Optional[List[NewValue]] = None,
parent: Optional[QObject] = None) -> None:
super().__init__(parent)
self._ref_namedlist = None self._ref_namedlist = None
self._roles: Tuple[str, ...] = () self._roles: Tuple[str, ...] = ()
self._list: list = [] self._list: list = []

View File

@ -8,7 +8,10 @@ from .list_model import ListModel
class ListModelMap(QObject): class ListModelMap(QObject):
def __init__(self) -> None: def __init__(self) -> None:
super().__init__() super().__init__()
self.dict: DefaultDict[Any, ListModel] = DefaultDict(ListModel)
# Set the parent to prevent item garbage-collection on the C++ side
self.dict: DefaultDict[Any, ListModel] = \
DefaultDict(lambda: ListModel(parent=self))
@pyqtSlot(str, result="QVariant") @pyqtSlot(str, result="QVariant")
@ -21,6 +24,7 @@ class ListModelMap(QObject):
def __setitem__(self, key, value: ListModel) -> None: def __setitem__(self, key, value: ListModel) -> None:
value.setParent(self)
self.dict[key] = value self.dict[key] = value