[PyQt] QML, pyqtSlot and ownership

Phil Thompson phil at riverbankcomputing.com
Sun Jul 20 18:05:56 BST 2014


On 14/07/2014 4:49 pm, Nenad Ognjanovic wrote:
> Phil Thompson <phil <at> riverbankcomputing.com> writes:
> 
>> 
>> How would it work in C++?
>> 
>> In other words, is the PyQt behaviour correct and in C++ you rely on
>> memory leaks (ie. the object existing without there being a reference
>> to it)?
>> 
>> Or is there a PyQt ownership bug?
>> 
> 
> As far as the first scenario goes (returning QObjects from slots), the
> object does get garbage collected by the QML engine so it's not exactly 
> a
> memory leak. I also cannot claim that it's a PyQt bug, but from Qt
> framework standpoint the documentation does say that the C++ object
> ownership should be taken over by QML if the parent wasn't assigned to
> the instantiated object:
> 
>> When data is transferred from C++ to QML, the ownership of the data
>> always remains with C++. The exception to this rule is when a QObject
>> is returned from an explicit C++ method call: in this case, the QML
>> engine assumes ownership of the object, unless the ownership of the
>> object has explicitly been set to remain with C++ by invoking
>> QQmlEngine::setObjectOwnership() with QQmlEngine::CppOwnership
>> specified.
>> 
>> Additionally, the QML engine respects the normal QObject parent
>> ownership semantics of Qt C++ objects, and will not ever take 
>> ownership
>> of a QObject instance which already has a parent.
> 
> link:
> http://qt-project.org/doc/qt-5/qtqml-cppintegration-data.html#data-ownership
> 
> The problem when python comes into play is that object never reaches 
> QML
> so it doesn't get a chance to get taken over. I'd expect PyQt to
> intervene here and keep the object alive, so that it's congruent with 
> the
> default Qt behavior.

I'll deal with this in a separate response.

> For the second one I'd expect it to also work, since the Dummy is being
> explicitly instantiated in QML. I figured it'd be best to provide 
> sample
> code for it also - I've posted it as a gist here:
> https://gist.github.com/bgr/5072f0bb3d1c5623b6c1 as well as attached to
> this message. If you comment out the sip.transferto call, it'll 
> segfault
> as soon as the list is scrolled. With the call in place, everything 
> works
> but the app doesn't exit on close.

The segfault is fixed in tonight's snapshot. A simple bug - not 
acquiring the GIL before garbage collecting the Dummy instance.

The not exiting is a side effect of objects being deleted in an order 
not expected by Qt. I recommend always creating the application instance 
at the module level, ie. move it out of your run() function. If not then 
explicitly delete objects in the right order. Another option might be to 
use the application as the parent of objects that don't currently have 
one.

Phil


More information about the PyQt mailing list