如何使用 QGraphicsView::RubberBandDrag? [英] how to use QGraphicsView::RubberBandDrag?

查看:67
本文介绍了如何使用 QGraphicsView::RubberBandDrag?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以提供一个解释,或者更好的简短示例,说明如何在 QGraphicsView 中使用 RubberBandDrag 枚举值?PyQt5 会很棒,但我可以从 C++ 版本翻译过来,如果有人愿意的话,可以提供有用的例子.

NoDragScrollHandDrag 相对容易理解(NoDrag 使鼠标成为一个指针,您可以捕获某些位置的点击,ScrollHandDrag 让鼠标变成一只手,你可以实现点击和拖动来滚动),但我不清楚 RubberBandDrag 可以用来做什么.

在有人说去阅读文档"之前,这里是提供的信息

而且 QRubberBand 通常仅旨在可视化选定区域,在 QGraphicsView 的情况下,如果它们是可选的,则选择该区域下方的项目(启用 QGraphicsItem::ItemIsSelectable 标志).

<小时>

根据您的最后一个问题:有没有办法在初始放置后使用它来拖动 QPolygon 的点?这将非常有用,在我看来你有一个 XY 问题 因为在术语中使用 drag 似乎让您认为它用于拖动元素,因为不,该拖动指的是创建橡皮筋的方式.

稍后我将展示如何实现顶点的拖动来修改QPolygon.

下面展示了如何通过鼠标拖动来修改顶点的位置:

导入数学从 PyQt5 导入 QtCore、QtGui、QtWidgets类 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_itemself.m_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):如果更改 == QtWidgets.QGraphicsItem.ItemPositionChange 和 self.isEnabled():self.m_annotation_item.movePoint(self.m_index, value)return super(GripItem, self).itemChange(change, value)类 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):如果 0 <= i 

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.

解决方案

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

这篇关于如何使用 QGraphicsView::RubberBandDrag?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆