[PyQt] Realizing memory used by signals with objects
Jan Kotanski
jan.kotanski at desy.de
Thu Apr 16 10:59:39 BST 2015
Hi,
I've just tested memory leaks in my application and I've accounted
a problem how to realize memory used by signals with objects, e.g.
QSignalMapper.mapped signal with a QWidget parameter.
After disconnecting this signal using garbage collector one can find
that PyQt leaves a weakref in the memory.
If I change the QWidget parameter to an int parameter this problem
disappears.
I've tested this issue in PyQt 4.9.3 (wheezy), 4.11.2 (jessie), 5.3.2
(jessie).
Is there any way to remove this weak reference (except catching it by gc)?
Bellow I append my test script for PyQt4.
Thanks,
Jan
from PyQt4.QtGui import (QWidget, QPushButton, QDialog, QVBoxLayout)
from PyQt4.QtCore import (QSignalMapper, pyqtSlot, QObject)
import sys
import gc
from collections import Counter
class Con(QObject):
def __init__(self, parent=None):
super(Con, self).__init__(parent)
self.mapper = QSignalMapper(self)
self.mapper.mapped.connect(self.checked)
@pyqtSlot(QWidget)
# @pyqtSlot(int)
def checked(self, widget):
print( "TYPE: %s" % type(widget))
def close(self):
self.mapper.mapped.disconnect(self.checked)
self.mapper.setParent(None)
self.mapper = None
class Dialog(QDialog):
def __init__(self, parent=None):
super(Dialog, self).__init__(parent)
self.button = QPushButton("Run")
vbl = QVBoxLayout()
vbl.addWidget(self.button)
self.con = None
self.setLayout(vbl)
self.button.clicked.connect(self.reset)
def test(self):
self.con = Con(self)
self.con.close()
self.con.setParent(None)
del self.con
self.con = None
@pyqtSlot()
def reset(self):
for i in range(1000):
self.test()
gc.collect()
print ("i = %s #OBJ = %s: %s" % (
i, len(gc.get_objects()),
Counter([type(g).__name__ for g in gc.get_objects()]
).most_common(4)))
def main():
from PyQt4.QtGui import QApplication
app = QApplication(sys.argv)
form = Dialog()
form.show()
app.exec_()
if __name__ == "__main__":
main()
More information about the PyQt
mailing list