如何擦除/删除QGraphicPathItem的特定部分?

2024-05-19 05:53:04 发布

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

我正在将QgraphicsPathItem添加到场景中,并希望擦除QgraphicsPathItem的特定部分。我在这里使用QgraphicsrectItem作为橡皮擦。两个项目都发生冲突,但QgraphicsPathItem没有被擦除。它在场景中保持不变。我将减去两条路径并将其添加到QgraphicsPathItem

class GraphicsSceneClass(QGraphicsScene):
    def __init__(self):
        super().__init__()
        self.setItemIndexMethod(QGraphicsScene.NoIndex)

        self.setBackgroundBrush(QBrush(Qt.black))
        self.setSceneRect(0,0,1000,1000)
        self.horizontal=QHBoxLayout()
        self.widget=QWidget()
        self.drawrect=False
        self.gridOn = 0
        self.selectionMode = 1
        self.targetForLine = QRect()
        self.drawEnd = True
        self.resizemode=0
        self.eraser_item = None
        self.erasing=False
        self.rect=QGraphicsRectItem()

    def mousePressEvent(self,event):
        try:
            sampleTransform = QTransform()
            self.objectAtMouse = self.itemAt(event.scenePos(), sampleTransform)
            if self.selectionMode == 2:
                if self.drawEnd == True:
                    self.drawEnd = False
                elif self.drawEnd == False:
                    self.drawEnd = True
                    self.drawLineObj = None
            if self.drawEnd == False:
                self.lineInsertPoint = self.TargPosForLine(event.scenePos(), "ForLine")
                tempPainterPath = QPainterPath()
                self.drawLineObj = QGraphicsPathItem()
                self.drawLineObj.setPos(self.lineInsertPoint.x(), self.lineInsertPoint.y())
                self.drawLineObj.setPen(QPen(Qt.NoPen))
                self.drawLineObj.setBrush(QBrush(QColor(Qt.gray)))
                self.drawLineObj.setPath(tempPainterPath)
                self.addItem(self.drawLineObj)
                self.drawLineObj.setFlag(QGraphicsItem.ItemIsSelectable)
            if event.buttons() == Qt.RightButton and self.resizemode == 1:
                self.erasing = True
                self.rect.setRect(event.scenePos().x()-5, event.scenePos().y()-5, 10, 10)
                print(event.pos().x(),event.pos().y())
                self.addItem(self.rect)
                self.rect.setPen(QColor(Qt.red))
        except Exception as e:
            print("Error in mousepress",e)
    def mouseMoveEvent(self,event):
        try:
            if self.selectionMode == 2 and self.drawEnd == False and self.erasing == False:
                f1 = QPainterPath()
                gridPos = self.TargPosForLine(event.scenePos(), "ForLine")
                f1.moveTo(0, 0)
                f1.lineTo(0, 6)
                f1.lineTo((gridPos.x() - self.lineInsertPoint.x()), 6)
                f1.lineTo((gridPos.x() - self.lineInsertPoint.x()), 0)
                f1.closeSubpath()
                self.drawLineObj.setPath(f1)
                self.drawLineObj.setPos(self.lineInsertPoint.x(), self.lineInsertPoint.y() + 5)
                self.drawLineObj.setBrush(QBrush(QColor(Qt.gray)))
                pen = QPen(QColor(Qt.gray))
                pen.setWidth(0)
                self.drawLineObj.setPen(pen)
                self.drawLineObj._property = []
                self.drawLineObj._angle = 0
            if self.selectionMode == 2 and self.drawEnd == True:
                self.targetForLine = self.TargPosForLine(event.scenePos(), "ForRect")
                self.update()
            if event.buttons() & Qt.RightButton and self.erasing:
                print(event.scenePos().x(),event.scenePos().y())

                self.rect.setRect(event.scenePos().x() - 5, event.scenePos().y() - 5,
                                         10, 10)

                for item in self.collidingItems(self.rect):
                    new = item.path()-(self.rect.shape())
                    item.setPath(new)
                    print('collided')

            else:
                self.targetForLine = QRect()

        except Exception as e:
            print("Error in mousemove",e)
    def mouseReleaseEvent(self, event):
        if self.drawrect==True or self.tLext==2 or self.tRext==2 or self.BLext==2 or self.BRext==2:
            self.drawrect=False
            self.tLext=0
            self.tRext=0
            self.BLext=0
            self.BRext=0
            QApplication.changeOverrideCursor(Qt.ArrowCursor)
            QApplication.setOverrideCursor(Qt.ArrowCursor)
            mainWindow.pointer.setChecked(False)
            if self.rect != None:
                self.removeItem(self.rect)

    def TargPosForLine(self, position, mode):
        try:
            clicked_column = int((position.y() // 16)) * 16
            clicked_row = int((position.x() // 16)) * 16
            if clicked_column < 0:
                clicked_column = 0
            if clicked_row < 0:
                clicked_row = 0
            if (mode == "ForRect"):
                return QRect(clicked_row, clicked_column, 16, 16)
            elif (mode == "ForLine"):
                return QPointF(clicked_row, clicked_column)
        except Exception as e:
            print("Error in TargPosForLine", e)

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.scene = GraphicsSceneClass()
        self.view=QGraphicsView(self.scene)
        self.view.setMouseTracking(True)
        self.view.setAcceptDrops(True)
        self.view.setRenderHint(QPainter.HighQualityAntialiasing)
        self.linePointerButton = QToolButton()
        self.linePointerButton.setCheckable(True)
        self.linePointerButton.setText("Drawline")
        self.linePointerButton.setToolTip("Draw Track")
        self.linePointerButton.clicked.connect(self.setPointerMode)
        self.resizebutton = QToolButton()
        self.resizebutton.setText("Resize")
        self.resizebutton.setCheckable(True)
        self.resizebutton.clicked.connect(self.resizepath)
   
        self.widg=QWidget()
        self.horizontal=QHBoxLayout()
        self.horizontal.addWidget(self.view)
        self.widg.setLayout(self.horizontal)
        self.setCentralWidget(self.widg)
        self.tool=self.addToolBar("Tool")
        self.tool.addWidget(self.linePointerButton)
        self.tool.addWidget(self.resizebutton)
    
    def keyPressEvent(self, event):
        try:
            key = event.key()
            if key == Qt.Key_Escape:
                but = self.linePointerButton
                self.scene.selectionMode = 1
                but.setChecked(True)
        except Exception:
            print("Keypress is not working")
    def setPointerMode(self):
        try:
            self.scene.selectionMode =2

        except Exception:
            print("Not able to change the selectionmode")
    def resizepath(self):
        self.scene.resizemode=1
        self.scene.selectionMode = 1
        self.linePointerButton.setChecked(False)
if __name__=="__main__":
    import sys
    app=QApplication(sys.argv)
    mainWindow = MainWindow()
    mainWindow.show()
    sys.exit(app.exec_())

Tags: rectselfeventfalsetrueifdefqt
1条回答
网友
1楼 · 发布于 2024-05-19 05:53:04

路径和item以及来自self.rect的形状不共享相同的坐标系。因此,当您要从线rect中删除橡皮擦时,必须使用公共坐标系(例如,您的场景之一):

for item in self.collidingItems(self.rect):
                    new = item.mapToScene(item.path())-self.rect.mapToScene(self.rect.shape()) # translate the paths to the scene coords system
                    item.setPath(item.mapFromScene(new)) # translate the path from the scene coords system

相关问题 更多 >

    热门问题