ironmantis7x
ironmantis7x

Reputation: 827

How can I display a PNG or JPEG in a QGraphicsView?

I have a pyqt5 GUI where I have a window that needs to display an output image when I click a button (called "Show Image").

I have made functions and linked them to the button, but when I press the button, the image does not show.

What is the correct way to achieve this?

Here is my code:

from PyQt5.QtCore import QCoreApplication, QRectF
from PyQt5.QtGui import QPixmap
from PyQt5 import QtCore, QtGui, QtWidgets, Qt
from PIL import Image, ImageQt, ImageEnhance
import sys
import time

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1200, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.graphicsView = QtWidgets.QGraphicsView(self.centralwidget)
        self.graphicsView.setGeometry(QtCore.QRect(560, 0, 640, 480))
        self.graphicsView.setObjectName("graphicsView")
        self.RunButton = QtWidgets.QPushButton(self.centralwidget)
        self.RunButton.setGeometry(QtCore.QRect(560, 490, 99, 41))
        self.RunButton.setObjectName("RunButton")
        self.ShowIButton = QtWidgets.QPushButton(self.centralwidget)
        self.ShowIButton.setGeometry(QtCore.QRect(660, 490, 99, 41))
        self.ShowIButton.setObjectName("ShowIButton")
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1200, 25))
        self.menubar.setObjectName("menubar")
        self.menuFile = QtWidgets.QMenu(self.menubar)
        self.menuFile.setObjectName("menuFile")
        self.menuStudy = QtWidgets.QMenu(self.menubar)
        self.menuStudy.setObjectName("menuStudy")
        self.menuDocuments = QtWidgets.QMenu(self.menubar)
        self.menuDocuments.setObjectName("menuDocuments")
        self.menuHelp = QtWidgets.QMenu(self.menubar)
        self.menuHelp.setObjectName("menuHelp")
        self.menuTools = QtWidgets.QMenu(self.menubar)
        self.menuTools.setObjectName("menuTools")
        MainWindow.setMenuBar(self.menubar)
        self.actionAbout = QtWidgets.QAction(MainWindow)
        self.actionAbout.setObjectName("actionAbout")
        self.actionNew = QtWidgets.QAction(MainWindow)
        self.actionNew.setObjectName("actionNew")
        self.actionOpen = QtWidgets.QAction(MainWindow)
        self.actionOpen.setObjectName("actionOpen")
        self.actionOpen_2 = QtWidgets.QAction(MainWindow)
        self.actionOpen_2.setObjectName("actionOpen_2")
        self.actionSave = QtWidgets.QAction(MainWindow)
        self.actionSave.setObjectName("actionSave")
        self.actionSave_As = QtWidgets.QAction(MainWindow)
        self.actionSave_As.setObjectName("actionSave_As")
        self.actionClose = QtWidgets.QAction(MainWindow)
        self.actionClose.setObjectName("actionClose")
        self.actionQuit = QtWidgets.QAction(MainWindow)
        self.actionQuit.setObjectName("actionQuit")
        self.actionTrain_Baseline = QtWidgets.QAction(MainWindow)
        self.actionTrain_Baseline.setObjectName("actionTrain_Baseline")
        self.actionTrain_Data_Set = QtWidgets.QAction(MainWindow)
        self.actionTrain_Data_Set.setObjectName("actionTrain_Data_Set")
        self.actionPatient = QtWidgets.QAction(MainWindow)
        self.actionPatient.setObjectName("actionPatient")
        self.actionGroup = QtWidgets.QAction(MainWindow)
        self.actionGroup.setObjectName("actionGroup")
        self.actionView = QtWidgets.QAction(MainWindow)
        self.actionView.setObjectName("actionView")
        self.menuFile.addAction(self.actionNew)
        self.menuFile.addAction(self.actionOpen_2)
        self.menuFile.addAction(self.actionSave)
        self.menuFile.addAction(self.actionSave_As)
        self.menuFile.addAction(self.actionClose)
        self.menuFile.addAction(self.actionQuit)
        self.menuStudy.addAction(self.actionPatient)
        self.menuStudy.addAction(self.actionGroup)
        self.menuDocuments.addAction(self.actionView)
        self.menuHelp.addAction(self.actionAbout)
        self.menuTools.addSeparator()
        self.menuTools.addAction(self.actionTrain_Baseline)
        self.menuTools.addAction(self.actionTrain_Data_Set)
        self.menubar.addAction(self.menuFile.menuAction())
        self.menubar.addAction(self.menuStudy.menuAction())
        self.menubar.addAction(self.menuDocuments.menuAction())
        self.menubar.addAction(self.menuTools.menuAction())
        self.menubar.addAction(self.menuHelp.menuAction())

        self.retranslateUi(MainWindow)
        self.ShowIButton.clicked.connect(self.graphicsView.show)
        #SQtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWIndow"))
        self.RunButton.setText(_translate("MainWindow", "Run"))
        self.ShowIButton.setText(_translate("MainWindow", "Show Image"))
        self.menuFile.setTitle(_translate("MainWindow", "File"))
        self.menuStudy.setTitle(_translate("MainWindow", "Study"))
        self.menuDocuments.setTitle(_translate("MainWindow", "Documents"))
        self.menuHelp.setTitle(_translate("MainWindow", "Help"))
        self.menuTools.setTitle(_translate("MainWindow", "Tools"))
        self.actionAbout.setText(_translate("MainWindow", "About"))
        self.actionNew.setText(_translate("MainWindow", "New"))
        self.actionOpen.setText(_translate("MainWindow", "Open"))
        self.actionOpen_2.setText(_translate("MainWindow", "Open"))
        self.actionSave.setText(_translate("MainWindow", "Save"))
        self.actionSave_As.setText(_translate("MainWindow", "Save As ..."))
        self.actionClose.setText(_translate("MainWindow", "Close"))
        self.actionQuit.setText(_translate("MainWindow", "Quit"))
        self.actionTrain_Baseline.setText(_translate("MainWindow", "Train Baseline"))
        self.actionTrain_Data_Set.setText(_translate("MainWindow", "Train Data Set"))
        self.actionPatient.setText(_translate("MainWindow", "Patient"))
        self.actionGroup.setText(_translate("MainWindow", "Group"))
        self.actionView.setText(_translate("MainWindow", "View"))

    def do_test(self):
        img = Image.open('image1.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.graphicsView.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.graphicsView.addPixmap(pixMap)
        self.graphicsView.fitInView(QRectF(0, 0, w, h), Qt.KeepAspectRatio)
        self.graphicsView.update()


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

Upvotes: 0

Views: 2070

Answers (1)

eyllanesc
eyllanesc

Reputation: 243897

As @musicamante points out you should not modify the file generated by pyuic so restore it, and I will assume that it is called gui.py.

Considering the above, your code has the following errors:

  • You are connecting the clicked signal to the show method of the QGraphicsView which will cause the QGraphicsView to be displayed when the button is pressed, but the QGraphicsView is already displayed so it will do nothing. Instead you should invoke the do_test method.

  • Your QGraphicsView does not have a scene so you cannot place anything.

  • Instead of trying several one QGraphicsPixmapItem it is better to reuse it making only the associated QPixmap update.

  • Do not use time.sleep in a GUI, if you want to do periodic tasks then you will have to use a counter with a QTimer.

A possible solution is the following code:

from PyQt5 import QtCore, QtGui, QtWidgets

from PIL import Image, ImageQt, ImageEnhance

from gui import Ui_MainWindow


class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)
        self.ShowIButton.clicked.connect(self.do_test)

        self.scene = QtWidgets.QGraphicsScene(self)
        self.graphicsView.setScene(self.scene)

        self.pixmap_item = self.scene.addPixmap(QtGui.QPixmap())

        self.level = 1
        self.enhancer = None
        self.timer = QtCore.QTimer(interval=500, timeout=self.on_timeout)

    @QtCore.pyqtSlot()
    def do_test(self):
        input_img = Image.open("image1.png")
        self.enhancer = ImageEnhance.Brightness(input_img)
        self.timer.start()
        self.ShowIButton.setDisabled(True)

    @QtCore.pyqtSlot()
    def on_timeout(self):
        if self.enhancer is not None:
            result_img = self.enhancer.enhance(self.level)
            qimage = ImageQt.ImageQt(result_img)
            self.pixmap_item.setPixmap(QtGui.QPixmap.fromImage(qimage))
        if self.level > 7:
            self.timer.stop()
            self.enhancer = None
            self.level = 0
            self.ShowIButton.setDisabled(False)
        self.level += 1


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

Upvotes: 2

Related Questions