What is the ‘correct’ or idiomatic way to cleanup/delete widgets when using PyQt4?
Consider the following code:
choices = ['a', 'b', 'c']
checkboxes = []
layout = QtGui.QVBoxLayout()
dialog = MyDialog()
for c in choices:
checkboxes.append(QtGui.QCheckBox(c)
layout.addWidget(chkbox)
dialog.setLayout(layout)
for c in checkboxes:
c.setParent(None)
c.deleteLater()
c = None
The above code uses setParent(), deleteLater(), and setting the object to None. Are all of these necessary?
Another possible scenario is I have a dialog with a bunch of widgets on it and want to remove these widgets and add new ones. I don’t want to ‘leak’ the old widgets, but I’m not sure what the correct way to do something like this would be.
It seems to me that deleteLater() might never be needed. Does it just decrement the reference count? If so, wouldn’t just setting the variable to None do the same thing?
First thing you should remember to do is to use the parent/child relationships for your widgets. When you do this, they will be owned by Qt and will automatically clean up all children when the parent is deleted.
In this situation, all the checkboxes will be properly cleaned up when you delete dialog. This handles one part of your question. I realize that you are implicitly having the parent set when you add them to the layout. But you should not then clear that parent before deleting. It is the parent relationship that allows the child to be automatically removed. Not a reference count. The reference aspect would be a python-side thing where it will get garbage collected when there are no more references to it.
deleteLateris very important, for use when you want the deletion to occur when control returns to the eventloop. It is also the safe way to delete widgets when you are removing some from a layout and adding new ones:These widgets will actually be deleted once this method has completed.
deleteLateris also useful for deleting the widget under which the slot or event is currently occurring. Such as a QPushButton that can delete itself on click.There is also not much need to set
c = None. Once a parent is deleted, and that triggers the deletion of all of its children, recursively, your python references to that object will be invalid. So all you need to do is to just not use them anymore. If they are in a list, clear the list. Accessing them would raise theRuntimeError: wrapped C/C++ object of %S has been deletedmeaning they are deleted.