Hello,
(Maybe this is not new to you, sorry if it's the case.)
I have been monitoring a big PyQt application lately, trying to reduce memory
usage. I noticed that QDialog causes memory leaks.
Using C++, one can use a dialog like this:
void function() {
MyDialog dlg(this);
dlg.exec();
}
The Python equivalent is:
def function(self):
dlg=MyDialog(self)
dlg.exec_loop()
Except that this is not totally equivalent:
- In the C++ version, dlg is a local variable: so it gets deleted when we get
out of function().
- In the Python version, dlg is owned by self: when we get out of function(),
it is still referenced and won't get garbage collected. A workaround to that
problem is to reparent the dialog, like this:
def function(self):
dlg=MyDialog(self)
dlg.exec_loop()
dlg.reparent(None, QPoint(0,0))
The attached Python example demonstrates this.
If there is a better solution, let me know.
--
Aurélien Gâteau - [EMAIL PROTECTED]
Dental-on-line
23 rue du Départ
75014 PARIS - FRANCE
import os
import sys
from qt import *
_statmFile=None
def logMemoryUsage(msg):
global _statmFile
if not _statmFile:
name=os.path.join("/proc", str(os.getpid()), "statm")
_statmFile=file(name)
_statmFile.seek(0)
txt=_statmFile.read().strip()
lst=txt.split()
# According to kernel doc, values after the third one are broken
lst=lst[:3]
print msg, ",".join(lst)
class Dialog(QDialog):
def __init__(self, parent):
QDialog.__init__(self, parent)
button=QPushButton("Ok", self)
QObject.connect(button, SIGNAL("clicked()"), self.accept)
# Allocate some big data to illustrate leak
self.bigData=[12]*2000000
class Window(QVBox):
def __init__(self):
QVBox.__init__(self)
button=QPushButton("Dialog (no reparent)", self)
QObject.connect(button, SIGNAL("clicked()"), self.openDialogNoReparent)
button=QPushButton("Dialog (reparent)", self)
QObject.connect(button, SIGNAL("clicked()"), self.openDialogReparent)
def openDialogNoReparent(self):
logMemoryUsage("Before")
dlg=Dialog(self)
dlg.exec_loop()
logMemoryUsage("After")
def openDialogReparent(self):
logMemoryUsage("Before")
dlg=Dialog(self)
dlg.exec_loop()
logMemoryUsage("After")
dlg.reparent(None, QPoint(0,0) )
def main():
app=QApplication(sys.argv)
win=Window()
win.show()
app.setMainWidget(win)
app.exec_loop()
if __name__=="__main__":
main()
_______________________________________________
PyKDE mailing list [email protected]
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde