Ошибка при сохранении изображения QGraphicsView в файл .png

Рейтинг: 1Ответов: 1Опубликовано: 08.05.2023

При попытке сохранения изображения с QGraphicsView, изображение сохраняется, но крашится программа без сообщений об ошибке, либо при первом нажатии на кнопку, которая запускает метод сохранения, либо после второго нажатия по кнопке.

В чём может быть проблема?

main.py:

from PyQt5.Qt import *
from Stackoverflow2_ui import *
import sys


class Mainwindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.scene = QGraphicsScene()
        self.scene.setSceneRect(0, 0, 500, 500)
        self.graphicsView.setScene(self.scene)
        self.scene.addRect(QRectF(0, 0, 500, 500), QPen(QColor(0, 0, 0)))
        self.scene.addRect(QRectF(200, 200, 100, 100), QPen(QColor(0, 0, 0)), QBrush(Qt.gray))
        self.pushButton_click.clicked.connect(self.save_view_on_picture)
        self.i = 0

    def save_view_on_picture(self):
        img = QImage(self.graphicsView.width(), self.graphicsView.height(), QImage.Format_ARGB8565_Premultiplied)
        img.fill(QColor(Qt.white))
        painter = QPainter(img)
        self.graphicsView.render(painter)
        img.save(f'img{self.i}.PNG')
        self.i += 1

if __name__ == '__main__':
    app = QApplication(sys.argv)
    graphics_view = Mainwindow()
    graphics_view.show()
    sys.exit(app.exec_())

Stackoverflow2_ui.py

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1119, 830)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.graphicsView = QtWidgets.QGraphicsView(self.centralwidget)
        self.graphicsView.setGeometry(QtCore.QRect(40, 60, 811, 561))
        self.graphicsView.setObjectName("graphicsView")
        self.pushButton_click = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_click.setGeometry(QtCore.QRect(940, 270, 111, 23))
        self.pushButton_click.setCheckable(True)
        self.pushButton_click.setObjectName("pushButton_click")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1119, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton_click.setText(_translate("MainWindow", "PushButton_click"))


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

Ответы

▲ 1Принят

bool QPainter::end()

Заканчивает painting. Любые ресурсы, используемые во время рисования, высвобождаются.
Обычно вам не нужно вызывать это, так как оно вызывается деструктором.
Возвращает true, если рисовальщик больше не активен; в противном случае возвращает false.

import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.Qt import *

#from Stackoverflow2_ui import Ui_MainWindow
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1119, 830)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.graphicsView = QtWidgets.QGraphicsView(self.centralwidget)
        self.graphicsView.setGeometry(QtCore.QRect(40, 60, 811, 561))
        self.graphicsView.setObjectName("graphicsView")
        self.pushButton_click = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_click.setGeometry(QtCore.QRect(940, 270, 111, 23))
        self.pushButton_click.setCheckable(True)
        self.pushButton_click.setObjectName("pushButton_click")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1119, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton_click.setText(_translate("MainWindow", "PushButton_click"))


class Mainwindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        
        self.scene = QGraphicsScene()
        self.scene.setSceneRect(0, 0, 500, 500)
        self.graphicsView.setScene(self.scene)
        self.scene.addRect(QRectF(0, 0, 500, 500), QPen(QColor(0, 0, 0)))
        self.scene.addRect(QRectF(200, 200, 100, 100), QPen(QColor(0, 0, 0)), 
            QBrush(Qt.gray))

        self.pushButton_click.clicked.connect(self.save_view_on_picture)
        self.i = 0

    def save_view_on_picture(self):
        img = QImage(
            self.graphicsView.width(), 
            self.graphicsView.height(), 
            QImage.Format_ARGB8565_Premultiplied
        )
        img.fill(QColor(Qt.white))
        painter = QPainter(img)
        
        self.graphicsView.render(painter)
        img.save(f'img_q1518299_{self.i}.PNG')
        
        painter.end()                                      # !!! +++ 

        self.i += 1


if __name__ == '__main__':
    app = QApplication(sys.argv)
    graphics_view = Mainwindow()
    graphics_view.show()
    sys.exit(app.exec_())

введите сюда описание изображения