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:
		@@ -5,15 +5,17 @@ from typing import (
 | 
			
		||||
 | 
			
		||||
from namedlist import namedlist
 | 
			
		||||
from PyQt5.QtCore import (
 | 
			
		||||
    QAbstractListModel, QModelIndex, Qt, pyqtProperty, pyqtSlot
 | 
			
		||||
    QAbstractListModel, QModelIndex, QObject, Qt, pyqtProperty, pyqtSlot
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
NewValue = Union[Mapping[str, Any], Sequence]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ListModel(QAbstractListModel):
 | 
			
		||||
    def __init__(self, initial_data: Optional[List[NewValue]] = None) -> None:
 | 
			
		||||
        super().__init__()
 | 
			
		||||
    def __init__(self,
 | 
			
		||||
                 initial_data: Optional[List[NewValue]] = None,
 | 
			
		||||
                 parent:       Optional[QObject]        = None) -> None:
 | 
			
		||||
        super().__init__(parent)
 | 
			
		||||
        self._ref_namedlist          = None
 | 
			
		||||
        self._roles: Tuple[str, ...] = ()
 | 
			
		||||
        self._list:  list            = []
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,10 @@ from .list_model import ListModel
 | 
			
		||||
class ListModelMap(QObject):
 | 
			
		||||
    def __init__(self) -> None:
 | 
			
		||||
        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")
 | 
			
		||||
@@ -21,6 +24,7 @@ class ListModelMap(QObject):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def __setitem__(self, key, value: ListModel) -> None:
 | 
			
		||||
        value.setParent(self)
 | 
			
		||||
        self.dict[key] = value
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user