how to use QGraphicsView::RubberBandDrag?

前端 未结 1 578
青春惊慌失措
青春惊慌失措 2020-12-21 15:06

Can somebody please provide an explanation, or better yet a short example, of how to use the RubberBandDrag enum value in QGraphicsView? PyQt5 wou

相关标签:
1条回答
  • 2020-12-21 15:31

    The QGraphicsView::RubberBandDrag flag only serves to activate the internal QRubberBand:

    And the QRubberBand in general only aims to visualize a selected area and in the case of QGraphicsView select the items below that area if they are selectable(enable QGraphicsItem::ItemIsSelectable flag).


    According to your last question: Is there a way to use this to drag points of a QPolygon around after initial placement? That would be really useful, it seems to me that you have an XY problem since it seems that the use of drag in the terminology makes you think that it serves to drag elements, because no, that drag refers to the way of creating the rubber band.

    In a few moments I will show how to implement the drag of the vertices to modify the QPolygon.

    The following shows how to modify the position of the vertices by dragging the mouse:

    import math
    
    from PyQt5 import QtCore, QtGui, QtWidgets
    
    
    class GripItem(QtWidgets.QGraphicsPathItem):
        circle = QtGui.QPainterPath()
        circle.addEllipse(QtCore.QRectF(-10, -10, 20, 20))
        square = QtGui.QPainterPath()
        square.addRect(QtCore.QRectF(-15, -15, 30, 30))
    
        def __init__(self, annotation_item, index):
            super(GripItem, self).__init__()
            self.m_annotation_item = annotation_item
            self.m_index = index
    
            self.setPath(GripItem.circle)
            self.setBrush(QtGui.QColor("green"))
            self.setPen(QtGui.QPen(QtGui.QColor("green"), 2))
            self.setFlag(QtWidgets.QGraphicsItem.ItemIsSelectable, True)
            self.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable, True)
            self.setFlag(QtWidgets.QGraphicsItem.ItemSendsGeometryChanges, True)
            self.setAcceptHoverEvents(True)
            self.setZValue(11)
            self.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
    
        def hoverEnterEvent(self, event):
            self.setPath(GripItem.square)
            self.setBrush(QtGui.QColor("red"))
            super(GripItem, self).hoverEnterEvent(event)
    
        def hoverLeaveEvent(self, event):
            self.setPath(GripItem.circle)
            self.setBrush(QtGui.QColor("green"))
            super(GripItem, self).hoverLeaveEvent(event)
    
        def mouseReleaseEvent(self, event):
            self.setSelected(False)
            super(GripItem, self).mouseReleaseEvent(event)
    
        def itemChange(self, change, value):
            if change == QtWidgets.QGraphicsItem.ItemPositionChange and self.isEnabled():
                self.m_annotation_item.movePoint(self.m_index, value)
            return super(GripItem, self).itemChange(change, value)
    
    
    class PolygonAnnotation(QtWidgets.QGraphicsPolygonItem):
        def __init__(self, parent=None):
            super(PolygonAnnotation, self).__init__(parent)
            self.m_points = []
            self.setZValue(10)
            self.setPen(QtGui.QPen(QtGui.QColor("green"), 2))
            self.setAcceptHoverEvents(True)
    
            self.setFlag(QtWidgets.QGraphicsItem.ItemIsSelectable, True)
            self.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable, True)
            self.setFlag(QtWidgets.QGraphicsItem.ItemSendsGeometryChanges, True)
    
            self.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
    
            self.m_items = []
    
        def addPoint(self, p):
            self.m_points.append(p)
            self.setPolygon(QtGui.QPolygonF(self.m_points))
            item = GripItem(self, len(self.m_points) - 1)
            self.scene().addItem(item)
            self.m_items.append(item)
            item.setPos(p)
    
        def movePoint(self, i, p):
            if 0 <= i < len(self.m_points):
                self.m_points[i] = self.mapFromScene(p)
                self.setPolygon(QtGui.QPolygonF(self.m_points))
    
        def move_item(self, index, pos):
            if 0 <= index < len(self.m_items):
                item = self.m_items[index]
                item.setEnabled(False)
                item.setPos(pos)
                item.setEnabled(True)
    
        def itemChange(self, change, value):
            if change == QtWidgets.QGraphicsItem.ItemPositionHasChanged:
                for i, point in enumerate(self.m_points):
                    self.move_item(i, self.mapToScene(point))
            return super(PolygonAnnotation, self).itemChange(change, value)
    
        def hoverEnterEvent(self, event):
            self.setBrush(QtGui.QColor(255, 0, 0, 100))
            super(PolygonAnnotation, self).hoverEnterEvent(event)
    
        def hoverLeaveEvent(self, event):
            self.setBrush(QtGui.QBrush(QtCore.Qt.NoBrush))
            super(PolygonAnnotation, self).hoverLeaveEvent(event)
    
    
    if __name__ == "__main__":
        import sys
    
        app = QtWidgets.QApplication(sys.argv)
        scene = QtWidgets.QGraphicsScene()
        w = QtWidgets.QGraphicsView(scene)
    
        polygon_item = PolygonAnnotation()
        scene.addItem(polygon_item)
        r = 100
        sides = 10
    
        for i in range(sides):
            angle = 2 * math.pi * i / sides
            x = r * math.cos(angle)
            y = r * math.sin(angle)
            p = QtCore.QPointF(x, y) + QtCore.QPointF(200, 200)
            polygon_item.addPoint(p)
    
        w.resize(640, 480)
        w.show()
        sys.exit(app.exec_())
    
    0 讨论(0)
提交回复
热议问题