如何在 QGraphicsView 中显示 png 或 jpeg?

How can I display a png or jpeg in a QGraphicsView?

我有一个 pyqt5 GUI,其中有一个 window 当我单击按钮(称为“显示图像”)时需要显示输出图像。

我制作了功能并将它们链接到按钮,但是当我按下按钮时,图像不显示。

有人能帮我找到实现这个目标的正确方法吗?

这是我的代码:

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_())

正如 @musicamante 所指出的,你不应该修改 pyuic 生成的文件,所以要恢复它,我假设它叫做 gui.py

综合以上情况,您的代码存在以下错误:

  • 您正在将点击信号连接到 QGraphicsView 的 show 方法,这将导致在按下按钮时显示 QGraphicsView,但 QGraphicsView 已经显示,因此它什么都不做。相反,您应该调用 do_test 方法。

  • 你的QGraphicsView没有场景所以你不能放置任何东西。

  • 与其尝试多个 QGraphicsPixmapItem,不如重用它,只更新关联的 QPixmap。

  • 不要在 GUI 中使用 time.sleep,如果你想做周期性任务,那么你将不得不使用带有 QTimer 的计数器。

一个可能的解决方案是下面的代码:

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_())