Issue
I can't seem to find much guidance on this issue anywhere online. I have been learning PySide and have noticed that half of the examples out there just set the parent
of QStuff to None
while other examples will set it to an object. I realize there may be a garbage collection issue at play. Say I have a QWidget object and I create and reference a QThing with its parent
set to QWidget, then I .add
the QThing to QWidget. It seems like I should then have circular references somewhere. Python does reference counting, so this would mean that the objects won't get garbage collected. Even something like
self.addWidget(QLabel('label', self))
would result in a circular reference (Though I imagine this case is handled by PySide.) Maybe I am worrying too much and all this is handled, I don't know.
In Short: What is the right way to use parents in PySide?
Solution
Two things at work here:
Qt
Qt organizes its object in object trees via the parent relationship. When you dispose an object all children are destroyed too (on the C side). Also properties like style are inherited via this relationship. It turns out that this is very useful for GUI objects, after all when you close a dialog you probably also want to get rid of the buttons in the dialog.
See also Object Trees & Ownership
Python (CPython)
Python deletes objects when they fall out of scope automatically. For example buttons that you thought you had disappear because Python garbage collected them already. Turns out that setting the parent correctly everywhere helps. For example with layouts the easiest way is to specify the parent directly in the construction of the layout (saves a call to setLayout
).
But if you still have a python reference to a button for example, but the widget was destroyed by Qt you may get a "RuntimeError: Internal C++ object already deleted.".
So a sufficient extent of setting parents helps a lot to write bugfree code with Qt and Python.
In your example:
self.addWidget(QLabel('label', self))
the parent is set twice after another. First when the inner part QLabel('label', self)
is created and second when addWidget
is called (see documentation of QLayout
). Instead of doing the same thing twice, why not only doing it once?
self.addWidget(QLabel('label'))
And for circular references per se, see Should I worry about circular references in Python?
Answered By - Trilarion
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.