如何使用 QGraphicsView::RubberBandDrag? [英] how to use QGraphicsView::RubberBandDrag?
问题描述
有人可以提供一个解释,或者更好的简短示例,说明如何在 QGraphicsView
中使用 RubberBandDrag
枚举值?PyQt5 会很棒,但我可以从 C++ 版本翻译过来,如果有人愿意的话,可以提供有用的例子.
NoDrag
和 ScrollHandDrag
相对容易理解(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屋!