Search code examples
pythonpyqtpyqt4pyqt5

pyqt5 i save the image but it is always empty


I am using PyQt5 to build a GUI and inside it I am using a Class Drawer to enable for the user to draw using the mouse but when I am saving the image it is always empty can any one tell me why?

class Drawer(QWidget):
   newPoint = pyqtSignal(QPoint)
   def __init__(self, parent=None):
      QWidget.__init__(self, parent)
      self.setAttribute(QtCore.Qt.WA_StaticContents)
      self.modified = False
      self.scribbling = False
      imageSize = QtCore.QSize(9500, 9500)
      h=400
      w=400
      self.myPenWidth = 13
      self.myPenColor = QtCore.Qt.black
      self.image = QtGui.QImage()
      self.image=QtGui.QImage(w,h,QtGui.QImage.Format_RGB32)



      self.path = QPainterPath()   


  def setPenColor(self, newColor):
     self.myPenColor = newColor

  def setPenWidth(self, newWidth):
     self.myPenWidth = newWidth

  def clearImage(self):
     self.path = QPainterPath() 
     self.image.fill(QtGui.qRgb(255, 255, 255))  ## switch it to else 
     self.modified = True
     self.update()


  def saveImage(self, fileName, fileFormat):
     self.image.save(fileName,fileFormat)



  def paintEvent(self, event):
     painter = QPainter(self)

     #painter.setPen(QColor(0, 0, 0))
     painter.setPen(QtGui.QPen(self.myPenColor, 
     self.myPenWidth,QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, 
     QtCore.Qt.RoundJoin))
     #painter.setFont(QFont('Decorative', 10))
     painter.drawImage(event.rect(), self.image)
     painter.drawPath(self.path)

  def mousePressEvent(self, event):
     self.path.moveTo(event.pos())
     self.update()

  def mouseMoveEvent(self, event):
     self.path.lineTo(event.pos())
     self.newPoint.emit(event.pos())
     self.update()

  def sizeHint(self):
     return QSize(300, 300)

when I am calling it i use this function that calls the function inside the Drawer class

def saveFile(self):#, fileFormat):

      fileFormat="PNG"
      fileName="ar.png"

      self.draw2.saveImage(fileName,fileFormat)

Solution

  • It is always empty because you have never painted the image, what you have painted has been the background of the QWidget, in the following code I have created a QPainter that takes as a base the image and draws on it and in the paintEvent() only the image is painted :

    import sys
    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    from PyQt5.QtWidgets import *
    
    
    class Drawer(QWidget):
        def __init__(self, parent=None):
            QWidget.__init__(self, parent)
            self.setAttribute(Qt.WA_StaticContents)
            h = 400
            w = 400
            self.myPenWidth = 13
            self.myPenColor = Qt.black
            self.image = QImage(w, h, QImage.Format_RGB32)
            self.path = QPainterPath()
            self.clearImage()
    
        def setPenColor(self, newColor):
            self.myPenColor = newColor
    
        def setPenWidth(self, newWidth):
            self.myPenWidth = newWidth
    
        def clearImage(self):
            self.path = QPainterPath()
            self.image.fill(Qt.white)  ## switch it to else
            self.update()
    
        def saveImage(self, fileName, fileFormat):
            self.image.save(fileName, fileFormat)
    
        def paintEvent(self, event):
            painter = QPainter(self)
            painter.drawImage(event.rect(), self.image, self.rect())
    
        def mousePressEvent(self, event):
            self.path.moveTo(event.pos())
    
        def mouseMoveEvent(self, event):
            self.path.lineTo(event.pos())
            p = QPainter(self.image)
            p.setPen(QPen(self.myPenColor,
                          self.myPenWidth, Qt.SolidLine, Qt.RoundCap,
                          Qt.RoundJoin))
            p.drawPath(self.path)
            p.end()
            self.update()
    
        def sizeHint(self):
            return QSize(300, 300)
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        w = QWidget()
        btnSave = QPushButton("Save image")
        btnClear = QPushButton("Clear")
        drawer = Drawer()
    
        w.setLayout(QVBoxLayout())
        w.layout().addWidget(btnSave)
        w.layout().addWidget(btnClear)
        w.layout().addWidget(drawer)
    
        btnSave.clicked.connect(lambda: drawer.saveImage("image.png", "PNG"))
        btnClear.clicked.connect(drawer.clearImage)
    
        w.show()
        sys.exit(app.exec_())