Brainless Duck
Brainless Duck

Reputation: 27

Crash when trying to paint on loaded QPixMap image

I'm working on a project that is basically Paint. I implemented opening file feature, so when I open file it loads into QPixmap.

The problem is: when I try to draw on successfully loaded QPixmap, my application crashes(no error or something, it just closes itself). I will provide my code for drawing and opening file. I think the rest(UI and etc.) isn't neccessary in this case.

Drawing:

class Canvas(QLabel):
    def __init__(self, parent=None):
        super().__init__(parent)
        p = self.palette()
        p.setColor(self.backgroundRole(), Qt.white)
        self.setAutoFillBackground(True)
        self.setPalette(p)
        self.myPixmap = QPixmap(600, 600)
        self.painter = QPainter(self.myPixmap)
        self.pen = QPen()
        self.painter.setPen(self.pen)
        self.painter.fillRect(0, 0, 600, 600, Qt.white)
        self.setPixmap(self.myPixmap)
        self.last = None    

    def mouseMoveEvent(self, event):
        if self.last:
            self.painter.setPen(self.pen)
            self.painter.drawLine(self.last, event.pos())

            self.last = event.pos()
            self.setPixmap(self.myPixmap)
            self.update()

    def mousePressEvent(self, event):
        self.last = event.pos()

    def mouseReleaseEvent(self, event):
        self.last = None

Opening file:

def openFile(self):
    openFile_file = QFileDialog.getOpenFileName(None, 'Open File:', '', 'Images (*.png *.bmp *.jpg)')
    openFile_ok = self.canvas.myPixmap.load(openFile_file[0])
    self.canvas.setPixmap(self.canvas.myPixmap)
    self.canvas.update()
    print('open', openFile_ok)

Upvotes: 1

Views: 586

Answers (1)

shao.lo
shao.lo

Reputation: 4626

The two main problems were 1) not ending the painting done in construction and 2) not resetting the painter after loading new image.

import sys
from PyQt5.QtGui import QPixmap, QPainter, QPen
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QLabel, QFileDialog

class Canvas(QLabel):
    def __init__(self, parent=None):
        super().__init__(parent)
        p = self.palette()
        p.setColor(self.backgroundRole(), Qt.white)
        self.setAutoFillBackground(True)
        self.setPalette(p)
        self.myPixmap = QPixmap(600, 600)
        self.painter = QPainter(self.myPixmap)
        self.pen = QPen()
        self.painter.setPen(self.pen)
        self.painter.fillRect(0, 0, 600, 600, Qt.white)
        self.painter.end()  # Need to end the painting here
        self.setPixmap(self.myPixmap)

        self.last = None
        self.image_loaded = False

    def mouseMoveEvent(self, event):
        if self.last:
            self.painter.setPen(self.pen)
            self.painter.drawLine(self.last, event.pos())

            self.last = event.pos()
            self.setPixmap(self.myPixmap)
            self.update()

    def mousePressEvent(self, event):
        if not self.image_loaded:
            self.openFile()
            self.image_loaded = True
        self.last = event.pos()

    def mouseReleaseEvent(self, event):
        self.last = None

    def openFile(self):
        openFile_file = QFileDialog.getOpenFileName(None, 'Open File:', '', 'Images (*.png *.bmp *.jpg)')
        openFile_ok = self.myPixmap.load(openFile_file[0])
        self.setPixmap(self.myPixmap)

        self.painter = QPainter(self.myPixmap)  # Need to reset the painter...there may be another method without creating a new painter
        self.painter.setPen(self.pen)

        self.update()
        print('open', openFile_ok)

app = QApplication(sys.argv)
label = Canvas()
label.show()
sys.exit(app.exec_())

Upvotes: 1

Related Questions