python - 用钢笔在 Canvas 上删除

标签 python pyqt pyqt5

我有一个功能正常的绘图应用程序,用于对图像进行一些分割。为此,我有两个图层,原始图像和我正在其上绘制的图像层。

我现在想实现一种删除方法。我已经实现了撤消功能,但我还希望用户能够选择画笔“颜色”,以便能够删除特定部分,例如油漆中的橡皮擦。我认为通过使用不透明的颜色进行绘制是可能的,但这只会导致不绘制任何线条。

因此,我的目标是画一条线,删除图像层中的像素值,以便我可以看到底层图像

绘图 MVP

from PyQt5.QtWidgets import QApplication, QMainWindow, QMenuBar, QMenu, QAction
from PyQt5.QtGui import QIcon, QImage, QPainter, QPen
from PyQt5.QtCore import Qt, QPoint
from PyQt5.QtGui import QColor
import sys

class Window(QMainWindow):
    def __init__(self):
        super().__init__()

        top = 400
        left = 400
        width = 800
        height = 600

        self.setWindowTitle("MyPainter")
        self.setGeometry(top, left, width, height)

        self.image = QImage(self.size(), QImage.Format_ARGB32)
        self.image.fill(Qt.white)
        self.imageDraw = QImage(self.size(), QImage.Format_ARGB32)
        self.imageDraw.fill(Qt.transparent)

        self.drawing = False
        self.brushSize = 2
        self.brushColor = Qt.black
        self.lastPoint = QPoint()

        self.change = False
        mainMenu = self.menuBar()
        changeColour = mainMenu.addMenu("changeColour")
        changeColourAction = QAction("change",self)
        changeColour.addAction(changeColourAction)
        changeColourAction.triggered.connect(self.changeColour)

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

    def mouseMoveEvent(self, event):
        if event.buttons() and Qt.LeftButton and self.drawing:
            painter = QPainter(self.imageDraw)
            painter.setPen(QPen(self.brushColor, self.brushSize,     Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
            painter.drawLine(self.lastPoint, event.pos())
            self.lastPoint = event.pos()
            self.update()

    def mouseReleaseEvent(self, event):
        if event.button == Qt.LeftButton:
            self.drawing = False

    def paintEvent(self, event):
        canvasPainter = QPainter(self)
        canvasPainter.drawImage(self.rect(), self.image, self.image.rect())
        canvasPainter.drawImage(self.rect(), self.imageDraw, self.imageDraw.rect())

    def changeColour(self):
        if not self.change:
            # erase
            self.brushColor = QColor(255,255,255,0)
        else:
            self.brushColor = Qt.black
        self.change = not self.change

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    app.exec()

如何删除像素子集?

在此示例中,应为 changeColour 函数中的 self.brushColor 指定什么颜色?

信息

白色不是解决方案,因为实际上底部的图像是一个复杂的图像,因此我想让顶部播放器在删除时再次“透明”。

最佳答案

您必须更改 compositionModeQPainter::CompositionMode_Clear 并用 eraseRect() 删除.

from PyQt5 import QtCore, QtGui, QtWidgets

class Window(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        top, left, width, height = 400, 400, 800, 600
        self.setWindowTitle("MyPainter")
        self.setGeometry(top, left, width, height)

        self.image = QtGui.QImage(self.size(), QtGui.QImage.Format_ARGB32)
        self.image.fill(QtCore.Qt.white)
        self.imageDraw = QtGui.QImage(self.size(), QtGui.QImage.Format_ARGB32)
        self.imageDraw.fill(QtCore.Qt.transparent)

        self.drawing = False
        self.brushSize = 2
        self._clear_size = 20
        self.brushColor = QtGui.QColor(QtCore.Qt.black)
        self.lastPoint = QtCore.QPoint()

        self.change = False
        mainMenu = self.menuBar()
        changeColour = mainMenu.addMenu("changeColour")
        changeColourAction = QtWidgets.QAction("change", self)
        changeColour.addAction(changeColourAction)
        changeColourAction.triggered.connect(self.changeColour)

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

    def mouseMoveEvent(self, event):
        if event.buttons() and QtCore.Qt.LeftButton and self.drawing:
            painter = QtGui.QPainter(self.imageDraw)
            painter.setPen(QtGui.QPen(self.brushColor, self.brushSize, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
            if self.change:
                r = QtCore.QRect(QtCore.QPoint(), self._clear_size*QtCore.QSize())
                r.moveCenter(event.pos())
                painter.save()
                painter.setCompositionMode(QtGui.QPainter.CompositionMode_Clear)
                painter.eraseRect(r)
                painter.restore()
            else:
                painter.drawLine(self.lastPoint, event.pos())
            painter.end()
            self.lastPoint = event.pos()
            self.update()

    def mouseReleaseEvent(self, event):
        if event.button == QtCore.Qt.LeftButton:
            self.drawing = False

    def paintEvent(self, event):
        canvasPainter = QtGui.QPainter(self)
        canvasPainter.drawImage(self.rect(), self.image, self.image.rect())
        canvasPainter.drawImage(self.rect(), self.imageDraw, self.imageDraw.rect())

    def changeColour(self):
        self.change = not self.change
        if self.change:
            pixmap = QtGui.QPixmap(QtCore.QSize(1, 1)*self._clear_size)
            pixmap.fill(QtCore.Qt.transparent)
            painter = QtGui.QPainter(pixmap)
            painter.setPen(QtGui.QPen(QtCore.Qt.black, 2))
            painter.drawRect(pixmap.rect())
            painter.end()
            cursor = QtGui.QCursor(pixmap)
            QtWidgets.QApplication.setOverrideCursor(cursor)
        else:
            QtWidgets.QApplication.restoreOverrideCursor()

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec())

关于python - 用钢笔在 Canvas 上删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53515295/

相关文章:

python - Python (PyQT) 中的 GUI 窗口闪烁并立即关闭?

python - 如何更新 Ui_MainWindow 中的 pyqt5 进度条

python - PyQt5 关闭事件方法

python - PyQt5 为每个组合框选项呈现不同的复选框集

windows - 卸载 PyQt5 以安装 PyQt4

python - 连接 pandas 数据帧 - 传递的所有对象都是 None

python - 如何递归迭代复杂的python对象?

python - 使用 cleanlooks 样式自定义 QRubberBand 外观

python - Google 自定义设备操作在 Raspberry Pi Google Assistant 上出现错误

python - 有没有办法让 django 中的每个 View 都执行一些东西?