Drawing with a brush

2019-03-06 00:20发布

问题:

I need help with the implementation of the brush on PyQt5 I already have some event code for the mouse:

def mousePressEvent(self, event):
    if event.button() and event.button() == Qt.LeftButton:
        self.lastPoint = event.pos()
        self.scribbling = True

def mouseMoveEvent(self, event):
    if (event.buttons() & Qt.LeftButton) and self.scribbling:
        self.drawLineTo(event.pos())


def mouseReleaseEvent(self, event):
    if event.button() == Qt.LeftButton and self.scribbling:
        self.drawLineTo(event.pos())
        self.scribbling = False

Inside of which the brush drawing function is declared:

def drawLineTo(self, endPoint):
    painter = QPainter(self.image)
    painter.setPen(QPen(self.myPenColor, self.myPenWidth, Qt.SolidLine,
            Qt.RoundCap, Qt.RoundJoin))
    painter.drawLine(self.lastPoint, endPoint)
    self.modified = True

    rad = self.myPenWidth / 2 + 2
    self.update(QRect(self.lastPoint, endPoint).normalized().adjusted(-rad, -rad, +rad, +rad))
    self.lastPoint = QPoint(endPoint)

But the main problem is that this function is declared in the events themselves. Therefore, drawing goes immediately, and I can not add other tools. Because together with them the "pencil" will constantly be drawn. But I need to somehow pull out the function from there and assign it to the corresponding button. To include only by clicking on this button. Let's say I have some toolbar:

toolbar = self.addToolBar('Инструменты')
toolbar.addAction(self.pen)

For which there is an action:

self.pen = QAction(QIcon('Image/pen.png'), 'Pencil', self)
self.pen.triggered.connect(self.      )

How would I do so in the "triggered.connect" assign the drawing function, and that it works only when the button is clicked. Maybe there are some bonds for this, like in tkinter, in the similarity:

def draw_pen(self):
    self.parent.config(cursor="arrow")
    self.parent.unbind("<Button-1>")
    self.parent.unbind("<Motion>")
    self.parent.bind("<ButtonPress-1>", self.button_press)
    self.parent.bind('<B1-Motion>', self.draw_pencil_move)
    self.parent.bind('<ButtonRelease-1>', self.draw_pencil_release)

And, in the end, I just assigned this function to the button, and everything worked fine

I will be very grateful for answers and especially for examples of solving problems or examples of brushes that are not declared in the events

P.S. I apologize for my English, if something is wrong с:

回答1:

Try it:

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

class MyScribbling(QMainWindow):

    def __init__(self):
        super().__init__()

        self.penOn = QAction(QIcon('Image/ok.png'), 'Включить рисование', self)
        self.penOn.triggered.connect(self.drawingOn)
        self.penOff = QAction(QIcon('Image/exit.png'), 'ВЫКЛЮЧИТЬ рисование', self)
        self.penOff.triggered.connect(self.drawingOff)
        toolbar = self.addToolBar('Инструменты')
        toolbar.addAction(self.penOn)
        toolbar.addAction(self.penOff)

        self.scribbling = False
        self.myPenColor = Qt.red      # +
        self.myPenWidth = 3           # +

        self.lastPoint = QPoint()
        self.image     = QPixmap("Image/picture.png")
        self.setFixedSize(600, 600)
        self.resize(self.image.width(), self.image.height())
        self.show()

    # +++ 
    def paintEvent(self, event):
        painter = QPainter(self)
        painter.drawPixmap(self.rect(), self.image)

    def mousePressEvent(self, event):
        # if event.button() and event.button() == Qt.LeftButton:    # -
        if (event.button() == Qt.LeftButton) and self.scribbling:   # +
            self.lastPoint = event.pos()
            # self.scribbling = True                                # -

    def mouseMoveEvent(self, event):
        if (event.buttons() & Qt.LeftButton) and self.scribbling:

            # self.drawLineTo(event.pos())                          # -

            # +++
            painter = QPainter(self.image)
            painter.setPen(QPen(self.myPenColor, self.myPenWidth, 
                                Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
            painter.drawLine(self.lastPoint, event.pos())
            # self.modified = True                                  # ?
            self.lastPoint = event.pos()
            self.update()

            # ?
            #rad = self.myPenWidth / 2 + 2
            #self.update(QRect(self.lastPoint, event.pos()).normalized().adjusted(-rad, -rad, +rad, +rad))
            #self.lastPoint = QPoint(event.pos())   

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton and self.scribbling:
            #self.drawLineTo(event.pos())
            #self.scribbling = False  
            pass

#    Перенес в mouseMoveEvent
#    def drawLineTo(self, endPoint):
#        painter = QPainter(self.image)
#        painter.setPen(QPen(self.myPenColor, self.myPenWidth, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
#        painter.drawLine(self.lastPoint, endPoint)
#        self.modified = True  
#        rad = self.myPenWidth / 2 + 2
#        self.update(QRect(self.lastPoint, endPoint).normalized().adjusted(-rad, -rad, +rad, +rad))
#        self.lastPoint = QPoint(endPoint)        

    # +++    
    def drawingOn(self):
        self.scribbling = True

    # +++    
    def drawingOff(self):
        self.scribbling = False


if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainMenu = MyScribbling()
    sys.exit(app.exec_())