Reputation: 21544
Here is a MCVE, very simple piece of code creating a QMainWindow
, with a central empty QWidget
:
import sys
from PyQt5.QtWidgets import QWidget
class MyWidget(QWidget):
"""QWidget based class to configure a Simulator object."""
def __init__(self,parent : QWidget):
"""
Construct a new object.
param: parent : QWidget
Parent class
"""
super().__init__(parent)
print("Created GUI")
def __del__(self):
print("Deleting GUI")
if __name__ == '__main__':
from PyQt5.QtWidgets import QMainWindow, QApplication
import logging
class CustomFormatter(logging.Formatter):
def format(self, record):
formatter = logging.Formatter("%(message)s")
return formatter.format(record)
logger = logging.getLogger("my_logger")
logger.setLevel(logging.INFO)
ch = logging.StreamHandler()
ch.setLevel(logging.INFO)
#ch.setFormatter(CustomFormatter())
logger.addHandler(ch)
app = QApplication(sys.argv)
wnd = QMainWindow()
widget = MyWidget(wnd)
wnd.setCentralWidget( widget )
wnd.show()
sys.exit(app.exec())
Execute it, a GUI opens, click the close button, GUI closes and output is then:
Created GUI
Deleting GUI
Now, uncomment ch.setFormatter(CustomFormatter())
, repeat.
Now output does not show Deleting GUI
. I tried to add an assert
here, code does not assert. Why does MyWidget.__del__
not get called when using a custom formatter?
Upvotes: 1
Views: 40
Reputation: 169338
If you mean to use __del__
for cleanup, you shouldn't. It's worth reading the myriad caveats the docs have about __del__
.
Context managers or close()
(and contextlib.closing()
to help along) are the Pythonic idiom for "disposable" objects.
Basically, I think it's likely just pure luck that setting up a formatter happens to create enough GC traffic that your Widget
does get __del__
'd before the interpreter shuts down (and Python likely (didn't check!) skips __del__
ing things when it's shutting down – little point in doing cleanup when the process will end anyway).
Wrapping your code in a def main():
(so the objects are locals, not globals) seems to (more) reliably make __del__
get called once widget
is no longer a local variable. So long as they're globals, they're still easily referred-to...
Upvotes: 2