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?
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With