断头画笔

2024-06-09 21:55:03 发布

您现在位置:Python中文网/ 问答频道 /正文

但在实施过程中,我遇到了一件我不清楚的事情。你知道吗

工作铅笔实现代码:

import sys
from PyQt5.QtCore import QPoint, QRect, QSize, Qt
from PyQt5.QtGui import QPainter, QPen, QIcon, QPixmap, QColor
from PyQt5.QtWidgets import (QAction, QApplication, QMainWindow,QWidget)


class AbstractScribbleArea(QWidget):
    def __init__(self, parent=None):
        super(AbstractScribbleArea, self).__init__(parent)
        self.modified = False
        self._begin = QPoint()
        self._end = QPoint()
        self._lastPoint = QPoint()
        self._pixmap = QPixmap()
        self._shape = ""

        self.myPenWidth = 10
        self.myPenColor = QColor("black")

    def mousePressEvent(self, event):
        if event.buttons() & Qt.LeftButton:
            self._begin = event.pos()
            self._end = event.pos()
            self.update()
        super(AbstractScribbleArea, self).mousePressEvent(event)

    def mouseMoveEvent(self, event):
        if event.buttons() & Qt.LeftButton:
            self._end = event.pos()
            self.update()
        super(AbstractScribbleArea, self).mouseMoveEvent(event)

    def mouseReleaseEvent(self, event):
        # draw on image
        painter = QPainter(self._pixmap)
        if self._shape == 'pencil':
            painter.setPen(QPen(self.myPenColor, self.myPenWidth,
                                Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
        self.draw(painter, self._begin, self._end, True)
        self._begin = QPoint()
        self._end = QPoint()
        self.update()
        super(AbstractScribbleArea, self).mouseReleaseEvent(event)

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.drawPixmap(self.rect(), self._pixmap, self.rect())
        if self._shape == 'pencil':
            painter.setPen(QPen(self.myPenColor, self.myPenWidth,
                                Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
        self.draw(painter, self._begin, self._end, False)

    def resizeEvent(self, event):
        w = self.width() if self.width() > self._pixmap.width() else self._pixmap.width()
        h = self.height() if self.height() > self._pixmap.height() else self._pixmap.height()

        s = QSize(w, h)
        if s != self._pixmap.size():
            pixmap = QPixmap(self._pixmap)
            self._pixmap = QPixmap(s)
            painter = QPainter(self._pixmap)
            painter.fillRect(QRect(0, 0, w, h), Qt.white)
            painter.drawPixmap(pixmap.rect(), pixmap)
        super(AbstractScribbleArea, self).resizeEvent(event)

    def draw(self, painter, _begin, _end, is_released):
        raise NotImplementedError

    def sizeHint(self):
        return QSize(640, 480)

    def set_shape(self, shape):
        self._shape = shape

    def shape(self):
        return self._shape



class ScribbleArea(AbstractScribbleArea):
    def draw(self, painter, _begin, _end, is_released):
        if _begin.isNull() or _end.isNull():
            return
        elif self.shape() == "pencil":
            self.drawPencil(painter, _begin, _end)

    def drawPencil(self, painter, _begin, _end):
        self.modified = True
        painter.drawPoint(_begin.x(), _end.y())

    def pencilOn(self):
        self.set_shape("pencil")


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.scribbleArea = ScribbleArea()
        self.setCentralWidget(self.scribbleArea)

        self.pen = QAction(QIcon('Image/pen.png'), 'Карандаш', self)
        self.pen.triggered.connect(self.scribbleArea.pencilOn)
        toolbar = self.addToolBar('Инструменты')
        toolbar.addAction(self.pen)


def main():
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

问题是,此时绘制的点可以沿轴移动。但这不是我在等的。我假设需要使用event.x()、event.y()来代替\u begin.x()、\u end.y()。你知道吗

但这不起作用,因为在draw函数中,我不能将参数传递给“event”。你知道吗

当我尝试执行类似的操作时,函数会使用=

def draw(self, painter, _begin, _end, is_released):
    if _begin.isNull() or _end.isNull():
        return
    elif self.shape() == "pencil":
        self.drawPencil(painter, event= #????)

def drawPencil(self, painter, _begin, _end):
    self.modified = True
    painter.drawPoint(event.x(), event.y())

我真的不明白需要传递给事件什么才能使函数工作。你知道吗

铅笔函数还有一个实现:

def draw_pencil(self, event):
    painter.drawLine(self.lastPoint, event.pos())
    self.modified = True
    self._lastPoint = event.pos()
    self.update()

Tags: selfeventifdefqtenddrawbegin
1条回答
网友
1楼 · 发布于 2024-06-09 21:55:03

似乎它还没有理解图形绘制逻辑的解决方案,在拖动鼠标的情况下,必须删除之前的图形,当鼠标被释放时,必须在永久内存中绘制,在这种情况下是QPixmap。但是对于铅笔,它是不同的,因为当它拖动的时候,它必须被画在永久内存中,所以实现它的类不适用于它,所以我们必须在新的类中实现它,记住在编程中你必须被排序,每个类必须有一个特定的任务。你知道吗

from PyQt5 import QtCore, QtGui, QtWidgets


class AbstractShapeScribbleArea(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(AbstractShapeScribbleArea, self).__init__(parent)
        self._start = QtCore.QPoint()
        self._end = QtCore.QPoint()
        self._pixmap = QtGui.QPixmap() 
        self._shape = ""

        self._color = QtGui.QColor("black")
        self._pen_width = 1

        self._pen = QtGui.QPen(self._color, self._pen_width, 
            QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin)

    def mousePressEvent(self, event):
        if event.buttons() & QtCore.Qt.LeftButton:
            self._start = event.pos()
            self._end = event.pos()
            self.update()
        super(AbstractShapeScribbleArea, self).mousePressEvent(event)

    def mouseMoveEvent(self, event):
        if event.buttons() & QtCore.Qt.LeftButton:
            self._end = event.pos()
            self.update()
        super(AbstractShapeScribbleArea, self).mouseMoveEvent(event)

    def mouseReleaseEvent(self, event):
        painter = QtGui.QPainter(self._pixmap)
        painter.setPen(self._pen)
        self.draw_shape(painter, self._start, self._end, True)

        self._start = QtCore.QPoint()
        self._end = QtCore.QPoint()
        self.update()
        super(AbstractShapeScribbleArea, self).mouseReleaseEvent(event)

    def paintEvent(self, event):
        painter = QtGui.QPainter(self)
        painter.drawPixmap(self.rect(), self._pixmap, self.rect())
        painter.setPen(self._pen)
        self.draw_shape(painter, self._start, self._end, False)

    def resizeEvent(self, event):
        w = self.width() if self.width() > self._pixmap.width() else self._pixmap.width()
        h = self.height() if self.height() > self._pixmap.height() else self._pixmap.height()

        s = QtCore.QSize(w, h)
        if s != self._pixmap.size():
            pixmap = QtGui.QPixmap(self._pixmap)
            self._pixmap = QtGui.QPixmap(s)
            painter = QtGui.QPainter(self._pixmap)
            painter.fillRect(QtCore.QRect(0, 0, w, h), QtCore.Qt.white)
            painter.drawPixmap(pixmap.rect(), pixmap)
        super(AbstractShapeScribbleArea, self).resizeEvent(event)

    def draw_shape(self, painter, start, end, is_released):
        raise NotImplementedError

    def sizeHint(self):
        return QtCore.QSize(640, 480)

    def set_pen_width(self, width):
        self._pen.setWidth(width)

    def set_pen_color(self, color):
        self._pen.setColor(QtGui.QColor(color))

    def set_shape(self, shape):
        self._shape =shape

    def shape(self):
        return self._shape


class ScribbleArea(AbstractShapeScribbleArea):
    def draw_shape(self, painter, start, end, is_released):
        if start.isNull() or end.isNull():
            return
        if self.shape() == "rectangle":
            self.draw_rectangle(painter, start, end)
        elif self.shape() == "ellipse":
            self.draw_ellipse(painter, start, end)

    def mousePressEvent(self, event):
        if self.shape() == "pencil" and event.buttons() & QtCore.Qt.LeftButton:
            setattr(self, "pencil_start", event.pos())
            self.draw_pencil(event.pos(), event.pos())
        else:
            super(ScribbleArea, self).mousePressEvent(event)

    def mouseMoveEvent(self, event):
        if self.shape() == "pencil" and event.buttons() & QtCore.Qt.LeftButton:
            pencil_start = getattr(self, "pencil_start")
            self.draw_pencil(pencil_start, event.pos())
            setattr(self, "pencil_start", event.pos())
        else:
            super(ScribbleArea, self).mouseMoveEvent(event)

    def mouseReleaseEvent(self, event):
        if self.shape() == "pencil":
            delattr(self, "pencil_start")
        else:
            super(ScribbleArea, self).mouseReleaseEvent(event)

    def draw_rectangle(self, painter, start, end):
        rect = QtCore.QRect(start, end)
        painter.drawRect(rect)

    def draw_ellipse(self, painter, start, end):
        rect = QtCore.QRect(start, end)
        painter.drawEllipse(rect)

    def draw_pencil(self, start, end):
        painter = QtGui.QPainter(self._pixmap)
        painter.setPen(self._pen)
        painter.drawLine(start, end)
        self.update()

    @QtCore.pyqtSlot()
    def rectangleOn(self):
        self.set_shape("rectangle")

    @QtCore.pyqtSlot()
    def ellipseOn(self):
        self.set_shape("ellipse")

    @QtCore.pyqtSlot()
    def pencilOn(self):
        self.set_shape("pencil")


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        scribbleArea = ScribbleArea()
        self.setCentralWidget(scribbleArea)

        rectangle = QtWidgets.QAction(QtGui.QIcon('Image/rectangle.png'), 'Rectangle', self)
        rectangle.triggered.connect(scribbleArea.rectangleOn)
        ellipse = QtWidgets.QAction(QtGui.QIcon('Image/Ellipse.png'), 'Ellipse', self)
        ellipse.triggered.connect(scribbleArea.ellipseOn)
        pen = QtWidgets.QAction(QtGui.QIcon('Image/pen.png'), 'Pencil', self)
        pen.triggered.connect(scribbleArea.pencilOn)
        toolbar = self.addToolBar('Tools')
        toolbar.addAction(rectangle)
        toolbar.addAction(ellipse)
        toolbar.addAction(pen)


if __name__ == '__main__':
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

相关问题 更多 >