<div dir="ltr"><div style="font-family:tahoma,sans-serif" class="gmail_default">​​</div><div class="gmail_default" style="font-family:tahoma,sans-serif">PyQt 5.7.</div><div class="gmail_default" style="font-family:tahoma,sans-serif"><br></div><div class="gmail_default" style="font-family:tahoma,sans-serif">I have a large body of existing UI code.  I have spent two days commenting in & out bits of code to try to discover why some of its <span style="font-family:monospace,monospace">QDialog</span>s "leak" after calling <span style="font-family:monospace,monospace">QDialog.exec()</span>.</div><div class="gmail_default" style="font-family:tahoma,sans-serif"><br></div><div class="gmail_default" style="font-family:tahoma,sans-serif">My definition of "leak" here is: after executing from somewhere else<br></div><div class="gmail_default" style="font-family:tahoma,sans-serif"><br></div><div class="gmail_default"><span style="font-family:monospace,monospace">dlg = QDialog(self)<br></span></div><div class="gmail_default" style="font-family:tahoma,sans-serif"><span style="font-family:monospace,monospace">QDialog.exec()</span><br></div><div class="gmail_default" style="font-family:tahoma,sans-serif"><br></div><div class="gmail_default" style="font-family:tahoma,sans-serif">the instance of the dialog stays in existence permanently (as long as the caller exists, which for me is till end of program).  That means that every time that code gets executed, yet another new dialog is left around in memory, which adds up over time.  All I do to test is go into the dialog and immediately close it.<br></div><div class="gmail_default" style="font-family:tahoma,sans-serif"><br></div><div class="gmail_default" style="font-family:tahoma,sans-serif">I discover this by inspecting <span style="font-family:monospace,monospace">QtWidgets.QApplication.allWidgets() </span>and reporting all <span style="font-family:monospace,monospace">QDialogs</span> which are still in existence.  I see an ever-increasing number of these dialogs, one per each time it's constructed and executed, when & only when the code in the dialog is as follows.</div><div class="gmail_default" style="font-family:tahoma,sans-serif"><br></div><div class="gmail_default" style="font-family:tahoma,sans-serif">I have finally tracked down the problematic line in the dialog's <span style="font-family:monospace,monospace">__init__()</span>.  Some of them have:</div><div class="gmail_default" style="font-family:tahoma,sans-serif"><br></div><div class="gmail_default" style="font-family:tahoma,sans-serif"><span style="font-family:monospace,monospace">from elsewhere import ensureValidDecimal<br>self.lineEdit = QLineEdit(self)<br>self.lineEdit.editingFinished.connect(lambda: ensureValidDecimal(self))</span><br></div><div class="gmail_default" style="font-family:tahoma,sans-serif"><br></div><div class="gmail_default" style="font-family:tahoma,sans-serif"><u><i>The vital bit is: they <span style="font-family:monospace,monospace">connect()</span> to a <span style="font-family:monospace,monospace">lambda</span> which references <span style="font-family:monospace,monospace"><b>self</b></span>.</i></u></div><div class="gmail_default" style="font-family:tahoma,sans-serif"><br></div><div class="gmail_default" style="font-family:tahoma,sans-serif">If the <span style="font-family:monospace,monospace">lambda</span> does not need to pass <span style="font-family:monospace,monospace">self</span> out as an argument, there will be no leak.</div><div class="gmail_default" style="font-family:tahoma,sans-serif"><br></div><div class="gmail_default" style="font-family:tahoma,sans-serif">If I go define (in this case) in the dialog (I actually sub-class from all my <span style="font-family:monospace,monospace">QDialog</span>s so I can add stuff) a dedicated function to avoid the <span style="font-family:monospace,monospace">lambda</span>:</div><div class="gmail_default"><span style="font-family:monospace,monospace"><br></span></div><div class="gmail_default"><span style="font-family:monospace,monospace">    def selfEnsureValidDecimal(self)</span></div><div class="gmail_default"><span style="font-family:monospace,monospace">        ensureValidDecimal(self)</span></div><div class="gmail_default"><span style="font-family:monospace,monospace"><br></span></div><div class="gmail_default" style="font-family:tahoma,sans-serif"><span style="font-family:monospace,monospace">    self.lineEdit.editingFinished.connect(self.selfEnsureValidDecimal)</span><br></div><div class="gmail_default" style="font-family:tahoma,sans-serif"><br></div><div class="gmail_default" style="font-family:tahoma,sans-serif">then there will also be no leak.</div><div class="gmail_default" style="font-family:tahoma,sans-serif"><br></div><div class="gmail_default" style="font-family:tahoma,sans-serif">I can see that at some deep level there must be a reference counting issue here.  In some shape or form, the fact that we have a <span style="font-family:monospace,monospace">lambda</span> which passes <span style="font-family:monospace,monospace">self</span> to the outside world must mean Python/PyQt wants to keep a reference to the dialog and this must be preventing its destruction.</div><div class="gmail_default" style="font-family:tahoma,sans-serif"><br></div><div class="gmail_default" style="font-family:tahoma,sans-serif">But I don't know what to do about it.  There is a lot of code with a lot of dialogs with all sorts of code attached.  So I need some kind of explanation of what exactly can or cannot be done here, what to look for in code, etc.  Note that I do <i>not</i> wish to use <span style="font-family:monospace,monospace">QDialog.setAttribute(QtCore.Qt.WA_DeleteOnClose, True)</span> on all my dialogs (I <i>believe</i> that would solve the leak, but it's not the point).  What must I <i>not</i> do if I do not expect such a self-reference to be left around preventing Python/PyQt from actually freeing up the dialog?<br></div><br><div>-- <br><div class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><span style="font-family:tahoma,sans-serif">Kindest,</span></div><div><span style="font-family:tahoma,sans-serif">Jonathan</span></div></div></div></div></div>
</div></div>