Issue
Consider the following code:
from PyQt4 import QtCore, QtGui, QtNetwork, QtWebKit
class ImageView(QtGui.QGraphicsView):
def __init__(self, file):
super().__init__()
self.setScene(QtGui.QGraphicsScene())
f = QtGui.QPixmap(QtGui.QImage(file))
# f = QtGui.QPixmap(file)
item = QtGui.QGraphicsPixmapItem(f)
self.scene().addItem(item)
def mousePressEvent(self, event):
self.scene().clear()
image = 'big.png'
app = QtGui.QApplication([])
view = ImageView(image)
view.show()
app.exec_()
Here I load a big (10000x10000px) image and display it in a QGraphicsView, and the scene then can be cleared with a mouse click. If the line f = QtGui.QPixmap(QtGui.QImage(file))
is used, then after clearing the scene the memory usage drops from 400 Mb to 20, showing that the image is cleared from memory. However, if I replace that line with f = QtGui.QPixmap(file)
, then after the same action memory usage remains at 400 Mb. It doesn't get reallocated later, either - if after clearing the scene I create another ImageView with another big image, another chunk gets allocated. Moreover, when I create QPixmap directly from file, I cannot free up the memory in any way whatsoever - I tried Python's deleteLater
, del
and gc module. This happens both in PyQt and Pyside. Why is this happening?
Solution
The QPixmap
methods that take a filename will do automatic caching via a QPixmapCache
. So it should be possible to free up memory like this:
QPixmapCache.clear()
The Qt docs state that the cache limit for QPixmapCache
is 10mb for desktop systems. However, this limit may be exceeded in practice. The reasons for this are somewhat obscure, but looking at the source reveals that Qt uses a QCache, and sets its maxCost to cache_limit * 1024
. However, the docs for totalCost say that this may be exceeded for implicitly shared classes (such as QPixmap
).
Answered By - ekhumoro
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.