Details
-
Bug
-
Resolution: Unresolved
-
P2: Important
-
None
-
5.15.2
-
None
-
Python 3.8.2
Description
Hi,
I have recently started experimenting with QUiLoader. I understand why it's better in the long run to use pyside2-uic, but I was playing with alternatives.
I noticed that if I register a custom widget class referenced in a .ui file, that the instance generated from QUiLoader.load isn't garbage collected at all. I compare this with the behaviour of widgets entirely created in Python code which are garbage collected.
The above behaviour isn't a problem until you have Python objects as instance attributes in those classes that need cleaning up (multiprocessing objects are what I ultimately have in mind). Because there is no garbage collection on the widgets, these too are never collected.
My initial suspicion was that the QUiLoader instance was keeping a reference to the generated widgets, but even del'ing that doesn't GC the widgets loaded. So I'm stumped.
I've put my reproducible into a gist: https://gist.github.com/foundry-markf/c2552b32f67720cf7f925d71a33e2186
Run the python script (tested in Python 3.8.2 against PySide2 5.15.2 - I've not tried regressing PySide2 versions), and it will open a main window with two buttons showing; one to create a QDialog from code, the other from a .ui file. Both share a Python code class, which is registered with the QUiLoader in the latter case. There is logging that it output to the console to show what is happening. Closing the dialogs generates more logging.
On my machine, this is the output from pressing the code dialog button and subsequently closing the dialog:
CRITICAL:root:PySide2 version: 5.15.2 CRITICAL:root:Opening dialog from code CRITICAL:root:External resource __init__ called CRITICAL:root:EmptyDialog __init__ called CRITICAL:root:EmptyDialog Qt object destroyed CRITICAL:root:SomethingWithExternalResources Qt object destroyed CRITICAL:root:Completed dialog from code CRITICAL:root:EmptyDialog __del__ called CRITICAL:root:External resource __del__ called
Also on my machine, this is the output for pressing the UI dialog button and then closing it:
CRITICAL:root:PySide2 version: 5.15.2 CRITICAL:root:Opening dialog from UI file CRITICAL:root:External resource __init__ called CRITICAL:root:EmptyDialog __init__ called CRITICAL:root:EmptyDialog Qt object destroyed CRITICAL:root:SomethingWithExternalResources Qt object destroyed CRITICAL:root:Completed dialog from UI file
Note the lack of two `_del_` calls at the end of the second run. This logging is from code shared between both runs of the test app.
Is this a bug?
Thanks