Displayin an Image in a QGraphicsScene

2020-02-26 01:55发布

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?

1条回答
相关推荐>>
2楼-- · 2020-02-26 02:37

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.

查看更多
登录 后发表回答