Skip to content

Instantly share code, notes, and snippets.

@justinfx
Last active August 29, 2015 14:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save justinfx/11016801 to your computer and use it in GitHub Desktop.
Save justinfx/11016801 to your computer and use it in GitHub Desktop.
A helper class for monitor widget growth and trying to track if instances are leaking
import pprint
import datetime
from collections import defaultdict
from PySide import QtCore, QtGui
class WidgetLeakWatcher(QtCore.QObject):
"""
Monitor the growth or existance of widgets in
the application, at intervals.
Modes::
MODE_ALL - Watch every type in the app, and report growth
MODE_TYPES - Watch specific types and report existing counts
Usage::
# Watch growth of all types
leaker = WidgetLeakWatcher(self)
leaker.start()
# Just keep printing a running total of all widgets
leaker = WidgetLeakWatcher(self)
leaker.setMode(leaker.MODE_TYPES)
leaker.start()
# Watch specific type counters
leaker = WidgetLeakWatcher(self)
leaker.setMode(leaker.MODE_TYPES)
leaker.setTypes([QtGui.QMenu, QtGui.QPushButton])
leaker.start()
"""
INTERVAL = 5000
MODE_ALL = 0
MODE_TYPES = 1
hasReported = QtCore.Signal()
def __init__(self, parent=None):
super(WidgetLeakWatcher, self).__init__(parent)
self.__widgetCounter = defaultdict(int)
self._timer = QtCore.QTimer(self)
self._timer.timeout.connect(self.report)
self.__mode = self.MODE_ALL
self.__types = tuple()
def start(self):
self._timer.start(self.INTERVAL)
def stop(self):
self._timer.stop()
def setTypes(self, types):
self.__types = tuple(types)
def setMode(self, mode):
self.__mode = mode
def report(self):
if self.__mode == self.MODE_ALL:
self._reportAll()
elif self.__mode == self.MODE_TYPES:
self._reportTypes()
else:
return
self.hasReported.emit()
def _reportTypes(self):
widgets = QtGui.qApp.allWidgets()
counter = defaultdict(int)
types = self.__types
if types:
for w in widgets:
if isinstance(w, types):
counter[w.__class__] += 1
if counter or not types:
print "\n[%s] %d objects" % (datetime.datetime.now(), len(widgets))
if counter:
ranking = sorted(counter.iteritems(), key=lambda i: i[1], reverse=True)
pprint.pprint(ranking)
def _reportAll(self):
widgets = QtGui.qApp.allWidgets()
counter = defaultdict(int)
for w in widgets:
counter[w.__class__] += 1
growth = {}
for typ, count in counter.iteritems():
prev = self.__widgetCounter[typ]
self.__widgetCounter[typ] = max(prev, count)
if count > prev:
growth[typ] = count
if growth:
ranking = sorted(growth.iteritems(), key=lambda i: i[1], reverse=True)
print "\n[%s] %d objects" % (datetime.datetime.now(), len(widgets))
pprint.pprint(ranking)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment