how to use QGraphicsView::RubberBandDrag?

徘徊边缘 提交于 2020-12-23 11:52:34

问题


Can somebody please provide an explanation, or better yet a short example, of how to use the RubberBandDrag enum value in QGraphicsView? PyQt5 would be great, but I can translate from the C++ version if that is preferred for whomever can provide a helpful exmaple.

NoDrag and ScrollHandDrag are relatively easy to understand (NoDrag makes the mouse a pointer and you can capture clicks at certain locations, ScrollHandDrag makes the mouse a hand and you can implement click and drag to scroll around), but I'm unclear on what RubberBandDrag can be used for.

Before somebody says "go read the docs", here is the information provided

https://doc.qt.io/qt-5/qgraphicsview.html

enum QGraphicsView::DragMode

QGraphicsView::RubberBandDrag

A rubber band will appear. Dragging the mouse will set the rubber band geometry, and all items covered by the rubber band are selected. This mode is disabled for non-interactive views.

This is clear but I'm not sure how I could actually use RubberBandDrag. Is there a way to use this to drag points of a QPolygon around after initial placement? That would be really useful.


回答1:


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_())


来源:https://stackoverflow.com/questions/60156142/how-to-use-qgraphicsviewrubberbanddrag

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!