Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Displayin an Image in a QGraphicsScene

Tags:

python

pyqt

pyqt4

I have a short script that modifies an image with PIL several times. I would like to be able to display the intermediate steps as it finishes with them, so I added a QGraphics Scene and I am trying to display the stages there. It will properly size and center the final stage (the last one posted before exiting the function), but it displays the intermediate steps without sizing or centering them.

The code to post the image is:

        #Code to generate the image and create the loop here...
        imgQ = ImageQt.ImageQt(img)
        pixMap = QtGui.QPixmap.fromImage(imgQ)

        scene = QtGui.QGraphicsScene()
        self.ui.previewGv.setScene(scene)
        pixMap = pixMap.scaled(self.ui.previewGv.size())
        #scene.clear()
        scene.addPixmap(pixMap)               
        self.ui.previewGv.repaint()
        self.ui.previewGv.show()

Is there some way to get it to properly display each stage?

like image 574
TimothyAWiseman Avatar asked Jan 07 '12 01:01

TimothyAWiseman


People also ask

How to show image in QGraphicsView?

Viewing an image There are just two buttons, Load and Clear . The load button brings up a file dialog, selecting a file loads it and displays into a QGraphicsView . The clear button, does what is expected. The layout of the buttons and the QGraphicsView is created with the gui designed in Qt Creator.


1 Answers

It is hard to determine your problem without loop code and working example. But i have similar test application, hope it will help.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import Image
import ImageQt
import ImageEnhance
import time

class TestWidget(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.scene = QGraphicsScene()
        self.view = QGraphicsView(self.scene)
        self.button = QPushButton("Do test")

        layout = QVBoxLayout()
        layout.addWidget(self.button)
        layout.addWidget(self.view)
        self.setLayout(layout)

        self.button.clicked.connect(self.do_test)

    def do_test(self):
        img = Image.open('image.png')
        enhancer = ImageEnhance.Brightness(img)
        for i in range(1, 8):
            img = enhancer.enhance(i)
            self.display_image(img)
            QCoreApplication.processEvents()  # let Qt do his work
            time.sleep(0.5)

    def display_image(self, img):
        self.scene.clear()
        w, h = img.size
        self.imgQ = ImageQt.ImageQt(img)  # we need to hold reference to imgQ, or it will crash
        pixMap = QPixmap.fromImage(self.imgQ)
        self.scene.addPixmap(pixMap)
        self.view.fitInView(QRectF(0, 0, w, h), Qt.KeepAspectRatio)
        self.scene.update()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    widget = TestWidget()
    widget.resize(640, 480)
    widget.show()

    sys.exit(app.exec_())

The main points:

  • If you are doing some processing or sleep in loop, you need to call QCoreApplication.processEvents() to allow Qt to do updates.

  • I'm saving reference to ImageQt.ImageQt (self.imgQ) or it will crash.

  • As I understood, you are creating QGraphicsScene in each iteration, better solution to create it once and then call scene.clear().

  • Scaling pixmap just to display it sized and centered is expensive, QGraphicsView.fitInView() maked for this purpose.

like image 180
reclosedev Avatar answered Sep 30 '22 16:09

reclosedev