[PyQt] Problems with QQmlListProperty and Qml object ownership

Juan Pedro Bolívar Puente raskolnikov at gnu.org
Tue Oct 29 00:23:12 GMT 2013


Hi!

I am using PyQt5 and while I love the approach I have found a couple of 
serious issues, the latter one becoming a real showstopper.  I have 
tried both with Qt 5.1 and 5.2.

1. Objects are not kept alive by Qml, meaning the application soon 
crashes if I do not keep the references alive.  I am now keeping all my 
objects alive, but sadly this means I have some memory leaks now.  Is 
there a way to fix it?  I was considering moving parts of the 
application to C++ in the future: can this problem be solved in C++ or 
is it an inherent limitation of Qml memory model?

2. I am having very weird crashes with QQmlListProperty. First, my usage 
of QQmlListProperty looks a bit like this (not exactly, but you get the 
idea):

class ListHolder(QObject):

     def __init__(self, wrapped_list):
         super(ConstListWrapper, self).__init__()
         self._wrapped_list = wrapped_list

     def __len__(self):
         return len(self._wrapped_list)

     def __getitem__(self, param):
         return self._wrapped_list[wrapped_list]

class SomeObjectWithAList(QObject):

     myListChanged = pyQtSignal(QQmlListProperty)

     @pyQtProperty(QQmlListWrapper)
     def myList(self):
         if self._list_holder is None:
             self._list_holder = ListHolder(self._the_list)
         if self._list_wrapper is None:
             self._list_wrapper = QQmlListProperty(
                 ListHolder,
                 self._list_holder,
                 count = len,
                 at = operator.getitem,
                 clear = lambda *a: None,
                 append = lambda *a: None)
         return self._list_wrapper

     def somethingChangedInTheList(self):
         self.myListChanged.emit(self.myList)

     ...

There are a couple of funny things in that code:

a) If I remove the clear and append operations, I get crashes more often.

b) In either case, when I bind the 'myList' property as model of 
Repeater or ListView elements, only the two first elements of the list 
are shown.

c) Most often when using the list in repeater or list views, the 
application crashes at the end on the garbage collector, in some 
Py_GetArgcArgv function called from PyDict_Contains called from 
_Py_GcObject_Track or something like that.

I have tried many variations of these, some of which do not involve the 
ListHolder object at all, but this is the "least crashing" variation I 
have so far...  Did I make a very stupid mistake? Google gives me very 
few cases of people using QQMlListProperty from PyQt, giving me the 
impression it might be a bit unsupported? Any clue?

Thanks a lot!

JP





More information about the PyQt mailing list