在pyqt5中使用QPainterPath填充绘制的路径

时间:2019-05-05 05:59:46

标签: python pyqt pyqt5 qpainterpath qgraphicspixmapitem

我有一个QGraphicsView,图像被加载到其中。然后创建它,这样您就可以用QPainterPath用指针绘制图像,然后通过连接起点和终点来关闭路径。我想知道如何在释放鼠标后填充该区域,然后使该对象可选但不可移动。

我尝试使用QPaint并填充addGraphicsItem函数中看到的路径。

class GraphicsView(QGraphicsView):
    def __init__(self, parent = None):
        super(GraphicsView, self).__init__(parent)
        self.setGeometry(300, 300, 250, 150)
        self.setScene(GraphicsScene(self))
        self.pixmapItem = QGraphicsPixmapItem() # check if everytime you open a new image the old image is still an item
        self.scene().addItem(self.pixmapItem)
        self.initial_path()

    def initial_path(self):
        self._path = QtGui.QPainterPath()
        pen = QtGui.QPen(QtGui.QColor("green"), 4, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap)
        self._path_item = self.scene().addPath(self._path, pen)

    @QtCore.pyqtSlot()
    def setImage(self):
        filename, _ = QFileDialog.getOpenFileName(None, "select Image", "", "Image Files (*.png *.jpg *jpg *.bmp)")
        if filename:
            self.image = QPixmap(filename)
            self.pixmapItem.setPixmap(QtGui.QPixmap(filename))

    def mousePressEvent(self, event):
        self.start = event.pos()
        if not self.pixmapItem.pixmap().isNull():
            self._path.moveTo(self.mapToScene(event.pos()))
            self._path_item.setPath(self._path)
        super(GraphicsView, self).mousePressEvent(event)

    def mouseMoveEvent(self, event):
        if not self.pixmapItem.pixmap().isNull():
            self._path.lineTo(self.mapToScene(event.pos()))
            self._path_item.setPath(self._path)
        super(GraphicsView, self).mousePressEvent(event)

    def mouseReleaseEvent(self, event):
        self.end = event.pos()
        if not self.pixmapItem.pixmap().isNull():
            self._path.lineTo(self.mapToScene(event.pos()))
            self._path.closeSubpath()
            self._path_item.setPath(self._path)
            self.addGraphicsItem()
            self.initial_path()
        super(GraphicsView, self).mouseReleaseEvent(event)

    def addGraphicsItem(self):
        pixmap = self.pixmapItem.pixmap()
        painter = QPainter(pixmap)
        painter.setRenderHint(QPainter.Antialiasing)
        pen = QPen(QtGui.QColor("green"), 4, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap)
        brush = QBrush(QColor('green'))
        painter.fillPath(self._path, brush)
        painter.end()

我希望addGraphicsItem函数可以填充该对象,但没有任何变化。

1 个答案:

答案 0 :(得分:1)

除了使用QPainter之外,您还可以使用setBrush方法继续使用QGraphicsPainterPath来设置背景色,还可以将标志QGraphicsItem :: ItemIsSelectable设置为可选:

from PyQt5 import QtCore, QtGui, QtWidgets


class GraphicsView(QtWidgets.QGraphicsView):
    def __init__(self, parent=None):
        super(GraphicsView, self).__init__(parent)
        self.setGeometry(300, 300, 250, 150)
        self.setScene(QtWidgets.QGraphicsScene(self))
        self.pixmapItem = (
            QtWidgets.QGraphicsPixmapItem()
        )  # check if everytime you open a new image the old image is still an item
        self.scene().addItem(self.pixmapItem)
        self._path_item = None

    def initial_path(self):
        self._path = QtGui.QPainterPath()
        pen = QtGui.QPen(
            QtGui.QColor("green"), 4, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap
        )
        self._path_item = self.scene().addPath(self._path, pen)

    @QtCore.pyqtSlot()
    def setImage(self):
        filename, _ = QtWidgets.QFileDialog.getOpenFileName(
            None, "select Image", "", "Image Files (*.png *.jpg *jpg *.bmp)"
        )
        if filename:
            self.pixmapItem.setPixmap(QtGui.QPixmap(filename))

    def mousePressEvent(self, event):
        start = event.pos()
        if (
            not self.pixmapItem.pixmap().isNull()
            and event.buttons() & QtCore.Qt.LeftButton
        ):
            self.initial_path()
            self._path.moveTo(self.mapToScene(start))
            self._path_item.setPath(self._path)
        super(GraphicsView, self).mousePressEvent(event)

    def mouseMoveEvent(self, event):
        if (
            not self.pixmapItem.pixmap().isNull()
            and event.buttons() & QtCore.Qt.LeftButton
            and self._path_item is not None
        ):
            self._path.lineTo(self.mapToScene(event.pos()))
            self._path_item.setPath(self._path)
        super(GraphicsView, self).mouseMoveEvent(event)

    def mouseReleaseEvent(self, event):
        end = event.pos()
        if (
            not self.pixmapItem.pixmap().isNull()
            and self._path_item is not None
        ):
            self._path.lineTo(self.mapToScene(end))
            self._path.closeSubpath()
            self._path_item.setPath(self._path)
            self._path_item.setBrush(QtGui.QBrush(QtGui.QColor("red")))
            self._path_item.setFlag(
                QtWidgets.QGraphicsItem.ItemIsSelectable, True
            )
            self._path_item = None
        super(GraphicsView, self).mouseReleaseEvent(event)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = GraphicsView()
    w.setImage()
    w.resize(640, 480)
    w.show()
    sys.exit(app.exec_())