Issue
I have a simple PyQt application. You can cycle through a folder of images using pageup and pagedown keys.
I am using the pixmap of a QLabel to display the images. The following logic actually works until you comment the processEvents call.
Any ideas on the cause of the crash and why adding processEvents prevents the crash?
# Python version: 2.7.9
# Qt version: 4.8.6
# PyQt version: 4.11.3
import sys
import os
from PIL import Image
from PIL import ImageOps
from PIL.ImageQt import ImageQt
from PyQt4 import QtGui
from PyQt4 import QtCore
from PyQt4 import Qt
imagefolder = "C:/Users/alan/Desktop/imagefolder"
class QExampleLabel (QtGui.QLabel):
def __init__(self, parentQWidget = None):
super(QExampleLabel, self).__init__(parentQWidget)
self.initUI()
def initUI (self):
self.imagelist = []
for path, subdirs, files in os.walk(imagefolder):
path = path.replace("\\", "/")
for file in files:
base, ext = os.path.splitext(file)
if ext.lower() == ".jpg":
jpg = path + "/" + file
self.imagelist.append(jpg)
self.i = -1
def keyPressEvent(self, keyevent):
event = keyevent.key()
if event == QtCore.Qt.Key_PageUp:
self.backward()
if event == QtCore.Qt.Key_PageDown:
self.forward()
def forward(self):
self.i = self.i + 1
if self.i >= len(self.imagelist):
self.i = len(self.imagelist) - 1
self.displayimage()
def backward(self):
self.i = self.i - 1
if self.i < 0:
self.i = 0
self.displayimage()
def displayimage(self):
photo = self.imagelist[self.i]
img = Image.open(photo)
mysize = (260,260)
method = Image.NEAREST if img.size == mysize else Image.ANTIALIAS
self.cropimage = ImageOps.fit(img, mysize, method = method, centering = (0.5,0.5))
qim = ImageQt(self.cropimage)
pix = QtGui.QPixmap.fromImage(qim)
self.setPixmap(pix)
QtGui.QApplication.processEvents() # comment this line to see setPixmap crash
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
myQExampleLabel = QExampleLabel()
myQExampleLabel.show()
myQExampleLabel.resize(260,260)
sys.exit(app.exec_())
Solution
The error is probably caused by garbage-collection, because you are not keeping an explicit reference to the Qt image object. When you create a pixmap from a QImage, the underlying data will remain shared, so use the QImage copy constructor to get an explicit reference, and then keep it alive until the pixmap is no longer needed:
self._img = QtGui.QImage(qim)
pix = QtGui.QPixmap.fromImage(self._img)
UPDATE:
Using the test case, I was able to eliminate the crash by simply keeping a reference to the original ImageQt
object:
self.qim = ImageQt(self.cropimage)
pix = QtGui.QPixmap.fromImage(self.qim)
self.setPixmap(pix)
Or, more simply, by using QPixmap.detach():
qim = ImageQt(self.cropimage)
pix = QtGui.QPixmap.fromImage(qim)
pix.detach()
self.setPixmap(pix)
Answered By - ekhumoro
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.