From 8582144e0e99dd6dd6d509170e14bb8f06cec990 Mon Sep 17 00:00:00 2001 From: wiredfool Date: Thu, 27 Oct 2016 13:57:11 -0700 Subject: [PATCH] Fix for issue #1370, Segfault using QImages due to not retaining the data --- PIL/ImageQt.py | 8 ++++-- Tests/test_image_toqimage.py | 48 +++++++++++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/PIL/ImageQt.py b/PIL/ImageQt.py index 3f7ae2518..2ce89e7ad 100644 --- a/PIL/ImageQt.py +++ b/PIL/ImageQt.py @@ -157,7 +157,6 @@ def _toqclass_helper(im): else: raise ValueError("unsupported image mode %r" % im.mode) - # must keep a reference, or Qt will crash! __data = data or align8to32(im.tobytes(), im.size[0], im.mode) return { 'data': __data, 'im': im, 'format': format, 'colortable': colortable @@ -175,8 +174,13 @@ if qt_is_installed: string or a PyQt string object). """ im_data = _toqclass_helper(im) + # must keep a reference, or Qt will crash! + # All QImage constructors that take data operate on an existing + # buffer, so this buffer has to hang on for the life of the image. + # Fixes https://github.com/python-pillow/Pillow/issues/1370 + self.__data = im_data['data'] QImage.__init__(self, - im_data['data'], im_data['im'].size[0], + self.__data, im_data['im'].size[0], im_data['im'].size[1], im_data['format']) if im_data['colortable']: self.setColorTable(im_data['colortable']) diff --git a/Tests/test_image_toqimage.py b/Tests/test_image_toqimage.py index 0dd9751d3..ccab08799 100644 --- a/Tests/test_image_toqimage.py +++ b/Tests/test_image_toqimage.py @@ -5,7 +5,17 @@ from PIL import ImageQt if ImageQt.qt_is_installed: - from PIL.ImageQt import QImage + from PIL.ImageQt import QImage, QPixmap + + try: + from PyQt5 import QtGui + except (ImportError, RuntimeError): + try: + from PyQt4 import QtGui + except (ImportError, RuntimeError): + from PySide import QtGui + + class TestToQImage(PillowQtTestCase, PillowTestCase): @@ -23,5 +33,41 @@ class TestToQImage(PillowQtTestCase, PillowTestCase): data.save(tempfile) + def test_segfault(self): + PillowQtTestCase.setUp(self) + + app = QtGui.QApplication([]) + ex = Example() + + +if ImageQt.qt_is_installed: + class Example(QtGui.QWidget): + + def __init__(self): + super(Example, self).__init__() + + img = hopper().resize((1000,1000)) + + qimage = ImageQt.ImageQt(img) + + pixmap1 = QtGui.QPixmap.fromImage(qimage) + + hbox = QtGui.QHBoxLayout(self) + + lbl = QtGui.QLabel(self) + # Segfault in the problem + lbl.setPixmap(pixmap1.copy()) + + + + +def main(): + app = QtGui.QApplication(sys.argv) + ex = Example() + sys.exit(app.exec_()) + + + + if __name__ == '__main__': unittest.main()