1

我有一个加载图像的 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 函数然后填充对象,但没有任何变化。

4

1 回答 1

1

除了使用 QPainter,您可以继续使用 QGraphicsPainterPath 使用 setBrush 方法,您可以设置背景颜色,此外,您可以将标志 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_())
于 2019-05-05T06:52:59.583 回答