Instantiating object without a reference in Qt for Python

I have just read an article about memory management stating that when using Qt for Python, “references to all created objects must be saved even if you are not going to use them”.

Although in this example the consequences are negligible, does this mean that instantiating e.g. labels in the following fashion is bad practice?

import sys
from PySide6.QtWidgets import QApplication, QLabel, QVBoxLayout, QWidget


class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        vb_main = QVBoxLayout()
        vb_main.addWidget(QLabel('Foo'))
        vb_main.addWidget(QLabel('Bar'))
        vb_main.addStretch()
        self.setLayout(vb_main)


def main():
    app = QApplication([])
    window = MainWindow()
    window.show()
    sys.exit(app.exec())


if __name__ == '__main__':
    main()

Answer

No, it is not a bad practice. The example provided in the article differs from the example you provide.

In the python binding of Qt there are 2 criterias that handle the memory:

  • Python: It is the usual handling that python does with references, that is, as long as an object is referenced in a scope then the object will not be eliminated.

  • Qt: Some objects (their memory) are handled by others for design reasons, and when that happens then it is explicitly pointed out by Qt in the documentation. An example of this case is the hierarchy tree of QObjects where a child of a QObject will have the same life cycle as its parent, and since QWidgets are QObjects then they will maintain that characteristic.

So if at least one of these criteria is met then the object will not be removed.


Original example translated to PySide6:

from PySide6.QtWidgets import QApplication, QLabel


def createLabel():
    label = QLabel("Hello, world!")
    label.show()


app = QApplication([])
createLabel()

app.exec()

In the original example, none is fulfilled since QLabel as a python variable has only a limited scope and does not have a QObject as parent.

On the other hand, in your example the second criterion is met since when adding it to a QLayout the latter will make the parent be the QWidget where it was established.